2012-11-08 60 views
3

我正在探索boost库代码,并发现以下奇怪的结构定义。奇怪的模板结构定义

struct add_ints_only 
{ 
    template<typename T> 
    struct result; 

    template <typename State, typename T> 
    struct result<add_ints_only(State, T)> // what's going on here? 
    { 
     typedef typename boost::remove_const< 
      typename boost::remove_reference<State>::type>::type type; 
    }; 

    template <typename State, typename T> 
    State 
    operator()(State const& state, T const& /*x*/) const 
    { 
     return state; 
    } 

    int 
    operator()(int state, int x) const 
    { 
     return x + state; 
    } 
}; 

这是什么?

回答

3

我想你正在寻找一些Boost.Fusion的东西或类似的东西。

特别是add_ints_only是Polymorphic Function Object概念的型号。

多态函数对象提供多态操作符(),它可能被重载或可能是一个模板。运算符()的结果类型可能因其参数类型而异。

它与STL的Adaptable Unary Function概念类似,它应该提供nested :: result_type。

但是,Polymorphic Function Object的结果类型可能因传递给operator()的参数类型而异。因此,应该使用比single :: result_type更强大的设施来获取基于operator()参数类型的结果类型。

template <typename State, typename T> 
struct result<add_ints_only(State, T)> // ... 

该语法是类的部分特化。

add_ints_only(State, T) 

是功能返回add_ints_only并采取阶段和T作为参数的类型。

本身,这种类型并非没有意义 - 你不会返回add_ints_only。它只是类型参数传递的简便形式 - 它看起来像add_ints_only函数的调用。它允许针对不同数量的参数进行专门化。

呢?这里是如何工作的:

live demo

#include <boost/utility/result_of.hpp> 
#include <typeinfo> 
#include <iostream> 
#include <ostream> 

using namespace std; 

struct PolymorphicFunctionObject 
{ 
    template<typename T> struct result; 

    template<typename Arg> 
    struct result< PolymorphicFunctionObject(Arg) > 
    { 
     typedef Arg type; 
    }; 

    template<typename Arg1,typename Arg2> 
    struct result< PolymorphicFunctionObject(Arg1,Arg2) > 
    { 
     typedef Arg2 type; 
    }; 

    template<typename Arg> 
    Arg operator()(Arg t) const 
    { 
     return t; 
    } 

    template<typename Arg1,typename Arg2> 
    Arg2 operator()(Arg1 t1,Arg2 t2) const 
    { 
     return t2; 
    } 
}; 

int main() 
{ 
    cout << typeid 
    (
     PolymorphicFunctionObject::result< PolymorphicFunctionObject(int) >::type 
    ).name() << endl; 
    // Output is - int 

    cout << typeid 
    (
     PolymorphicFunctionObject::result< PolymorphicFunctionObject(char,double) >::type 
    ).name() << endl; 
    // Output is - double 

    // ----------------- 
    // Or using boost::result_of, which queries ::result internally: 

    cout << typeid 
    (
     boost::result_of< PolymorphicFunctionObject(short) >::type 
    ).name() << endl; 
    // Output is - short 

    cout << typeid 
    (
     boost::result_of< PolymorphicFunctionObject(char,float) >::type 
    ).name() << endl; 
    // Output is - float 

    // ------------------ 
    // Or using C++11 decltype: 
    cout << typeid 
    (
     decltype(PolymorphicFunctionObject()(long())) 
    ).name() << endl; 
    // Output is - long 

    cout << typeid 
    (
     decltype(PolymorphicFunctionObject()(long(),unsigned())) 
    ).name() << endl; 
    // Output is - unsigned int 

} 

正如你所看到的,结果类型查询语法:

boost::result_of< PolymorphicFunctionObject(short) >::type 
boost::result_of< PolymorphicFunctionObject(char,float) >::type 

类似于普通的函数调用。

P.S.在C++ 11中,由于存在decltype,因此不需要这些东西,这可以用来自动获取结果类型。例如:

decltype(PolymorphicFunctionObject()(long(),unsigned())) 
3

result部分专门用于函数类型add_ints_only(State, T)

的目的是,要知道的是,算符add_ints_only返回特别参数类型可以通过写入查询的类型的代码:

typedef typename add_ints_only::result<add_ints_only(arg1_type, arg2_type)>::type 
    result_type; 

例如

template<typename U, typename V> void foo(U u, V v) { 
    typename add_ints_only::result<add_ints_only(arg1_type, arg2_type)>::type 
    result = add_ints_only()(u, v); 
} 

这对函数根据它们的operator()参数类型返回不同类型很有用。