2012-11-08 36 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()參數類型返回不同類型很有用。