2015-06-22 12 views
5

मैं एक प्रकार समारोह Tuple से लागू किया है इसी प्रकार का एक std::tuple में My_enum मानों की सूची बारी के एक टपल देता है:प्रकार समारोह है कि चुने हुए प्रकार

#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...>; 
}; 

अधिक सीधे आपके सवाल का जवाब करने के लिए, आप एक variadic प्राथमिक टेम्पलेट घोषणा कर सकते हैं, तो दो विशेषज्ञताओं लिखें: जब के लिए कम से कम दो पैरामीटर हैं, और जब केवल एक ही है:

//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

संबंधित मुद्दे