2013-07-24 17 views
6

मैं एक पैरामीटर के पैक में प्रकार A खोजने की कोशिश कर रहा हूँ:एक पैरामीटर पैक में एक प्रकार खोजने के

template <int I, typename A, typename B, typename ...C> 
struct index_of 
{ 
    static constexpr int const value = 
    std::is_same<A, B>::value ? I : index_of<I + 1, A, C...>::value; 
}; 

template <int I, typename A, typename B> 
struct index_of<I, A, B> 
{ 
    static constexpr int const value = 
    std::is_same<A, B>::value ? I : -1; 
}; 

यह काम करने लगता है, लेकिन मैं nontype पैरामीटर I, जो मैं करना चाहते हैं को खत्म करने में असमर्थ हूँ एक डिफ़ॉल्ट पैरामीटर होने के लिए, लेकिन अंत में पैरामीटर पैक की वजह से ऐसा नहीं कर सकता है। I को कैसे हटाएं/छुपाएं, इसलिए मेटाफंक्शन अधिक उपयोगकर्ता के अनुकूल हो जाता है?

उत्तर

3
template <typename A, typename B, typename... C> 
struct index_of 
{ 
    static constexpr int const value = 
    std::is_same<A, B>{} 
    ? 0 
    : (index_of<A, C...>::value >= 0) ? 1+index_of<A, C...>::value : -1; 
}; 

template <typename A, typename B> 
struct index_of<A, B> 
{ 
    static constexpr int const value = std::is_same<A, B>{} -1; 
}; 
का उपयोग कर

नोट std::is_same<A, B>{} -1bool से int पर एक रूपांतरण का उपयोग करता है।

template <typename A, typename B, typename... C> 
struct index_of 
    : std::integral_constant 
    < int, 
     std::is_same<A, B>{} 
     ? 0 
     : (index_of<A, C...>{} == -1 ? -1 : 1+index_of<A, C...>{}) 
    > 
{}; 

template <typename A, typename B> 
struct index_of<A, B> 
    : std::integral_constant < int, std::is_same<A, B>{} -1 > 
{}; 

आप प्रकार नहीं मिला है मामले में -1 वापस जाने के लिए की जरूरत नहीं है: (अगर कोई जानता है कि कैसे एक को शामिल करने


integral_constant से पाने से बेहतर static_assert यहां एक सुंदर नैदानिक ​​संदेश के लिए, मैं एक टिप्पणी/संपादन की सराहना करता हूं)

template <typename A, typename B, typename... C> 
struct index_of 
    : std::integral_constant < std::size_t, 
          std::is_same<A, B>{} ? 0 : 1+index_of<A, C...>{} > 
{}; 

template <typename A, typename B> 
struct index_of<A, B> 
    : std::integral_constant<std::size_t, 0> 
{ 
    constexpr operator std::size_t() const 
    { 
     return std::is_same<A, B>{} 
       ? 0 
       : throw std::invalid_argument("Type not found!"); 
    } 
}; 
+0

लेकिन दूसरा और तीसरा मेटाफंक्शन डुप्लिकेट का सही ढंग से समर्थन नहीं करता है। – user1095108

+0

@ user1095108 आप सही हैं, मैंने इसे ओवरम्प्लीफाइड किया है। फिक्स्ड। – dyp

6

आप एक नाम स्थान में इस कार्यान्वयन छिपाने के लिए और अन्य वर्ग एक डिफ़ॉल्ट पैरामीटर उदाहरण के साथ अपने कार्यान्वयन कॉल का उपयोग कर सकते हैं:

namespace detail 
{ 
    // your code as it is in the question 
} 

template <typename A, typename... B> 
struct index_of 
{ 
    static int const value = detail::index_of<0, A, B...>::value; 
}; 

संपादित

उसकी टिप्पणी DYP में डिफ़ॉल्ट के लिए सरल तरीका पता चलता है I एक उपनाम

template <typename A, typename... B> 
using index_of = detail::index_of<0, A, B...>; 
+2

सी ++ 11 में, आप एक उपनाम टेम्पलेट का भी उपयोग कर सकते हैं। – dyp

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