2015-06-22 86 views
5

我已經實現了一個類型的函數Tuple是轉My_enum值的列表到相應類型的std::tuple的元組類型的功能:返回選擇類型

#include <tuple> 

enum My_enum{ t_int, t_double }; 

// Bind_type is a type function that given a My_enum returns the corresponding type 
template<My_enum E> struct Bind_type; 
template<> struct Bind_type<t_int>{ using type = int; }; 
template<> struct Bind_type<t_double>{ using type = double; }; 

// Tuple is a type function that given a template value parameter pack of My_enums returns a std::tuple of correspondig types 
template<My_enum First, My_enum... Others> 
struct Tuple { 
    using type = decltype(std::tuple_cat(
       typename Tuple<First>::type{}, 
       typename Tuple<Others...>::type{} 
      )); 
}; 

template<> 
struct Tuple<t_int> { 
    using type = std::tuple<Bind_type<t_int>::type>; 
}; 
template<> 
struct Tuple<t_double> { 
    using type = std::tuple<Bind_type<t_double>::type>; 
}; 

我想能夠聲明在Tuple的遞歸基礎情況下,因爲我不想手動管理Tuple專業化,只要我向My_enum添加或刪除值,因爲它容易出錯(和無聊)。我試過了:

template<My_enum E> 
struct Tuple { 
    using type = std::tuple<Bind_type<E>::type>; 
}; 

但是這不是可變參數版本的有效特化。

我的問題是:當它只有一個模板值參數時,是否有巧妙的方法來聲明Tuple的專業化?

回答

6

您可以通過簡單的參數包直接擴大到std::tuple做到這一點沒有遞歸:

template<My_enum... Enums> 
struct Tuple { 
    using type = std::tuple<typename Bind_type<Enums>::type...>; 
}; 

更直接地回答你的問題,你可以聲明可變參數主要模板,然後寫兩個專業:何時至少有兩個參數,並且當只有一個參數時:

//primary template, takes any number of My_enums 
template <My_enum... Enums> 
struct Tuple { 
    //this case will be chosen if we instantiate a Tuple with no args 
    using type = std::tuple<>; 
} 

//specialization for when there are at least two arguments 
template<My_enum First, My_enum Second, My_enum... Others> 
struct Tuple<First,Second,Others...> { 
    using type = decltype(std::tuple_cat(
       typename Tuple<First>::type{}, 
       typename Tuple<Second,Others...>::type{} 
      )); 
}; 

//base case, only one argument left 
template<My_enum Last> 
struct Tuple<Last> { 
    using type = std::tuple<typename Bind_type<Last>::type>; 
}; 
+0

非常感謝您對這兩個答案:)。不知道我可以用這種方式來擴展參數包,並且在可變參數之前有兩個參數的技巧非常有趣。 –

+1

我發現這個問題真的很有幫助:http://stackoverflow.com/questions/17652412/what-are-the-rules-for-the-token-in-the-context-of-variadic-template。答案解釋了可變參數模板中elipsis(...)的正確使用和用例。 –

+1

請注意,零包大小的情況不能與上面的#2解決方案一起使用。你也需要'<>'專門化,這也可以放在主要的專業化。 – Yakk