2014-10-17 10 views
10

मान लीजिए मैं निम्नलिखित हस्ताक्षर के साथ एक वर्ग है:मैं वैरिएड टेम्पलेट तर्क वाले वर्ग को सक्षम कैसे करूं?

template <typename T, typename... Args> 
class A; 

लेकिन यह कैसे इस वर्ग के बर्ताव करता है कुछ अन्य पैरामीटर पर निर्भर होना चाहिए, मान लें कि यह T::value का क्या महत्व है करते हैं:

template <typename T, typename... Args, typename Enable> 
class A; 

template <typename T, typename... Args, typename = typename std::enable_if<T::value>::type> 
class A 
{ 
    // do something 
}; 

template <typename T, typename... Args, typename = typename std::enable_if<!T::value>::type> 
class A 
{ 
    // do something else 
}; 

int main() { return 0; } 

हालांकि, इस कार्यक्रम निम्नलिखित त्रुटि देता है:

prog.cpp:6:11: error: parameter pack ‘Args’ must be at the end of the template parameter list class A;

मैंनेके उपयोग पर जानकारी का एक अच्छा स्रोत खोजने के लिए संघर्ष किया है विविधता टेम्पलेट्स के साथ कक्षाओं का चयन करने के लिए। केवल सवाल मैं मिल सकता है इस एक है:

How to use std::enable_if with variadic template

लेकिन नाम के बावजूद, इस सवाल और उसके जवाब ज्यादा मदद नहीं कर रहे हैं। अगर कोई इस बात पर एक गाइड प्रदान या लिंक कर सकता है कि इसका संपर्क कैसे किया जाना चाहिए और इसकी सराहना क्यों की जाएगी।

उत्तर

8

सबसे पहले, आप क्या प्रयास कर रहे हैं कई परिभाषाएं लिख रहा है एक वर्ग टेम्पलेट का। इसकी अनुमति नहीं है क्योंकि यह एक परिभाषा नियम का उल्लंघन करता है। यदि आप कक्षाओं के साथ सशर्त सक्षम करना चाहते हैं, तो आपको विशेषज्ञता की आवश्यकता है। साथ ही, कंपाइलर त्रुटि संदेश ने आपको पहले ही बताया है, आपके पास पैरामीटर सूची के बीच में एक वैरिएडिक पैरामीटर पैक नहीं हो सकता है।

एक तरह से करने के लिए यह होगा: अगर हालत वास्तव में एक bool है

namespace detail { 

template<typename T, typename Enable, typename... Args> 
class A_impl; 

template<typename T, typename... Args> 
class A_impl<T, typename std::enable_if<T::value>::type, Args...> { 
    // code here 
}; 

template<typename T, typename... Args> 
class A_impl<T, typename std::enable_if<!T::value>::type, Args...> { 
    // code here 
}; 
} 

template<typename T, typename...Args> 
class A : public detail::A_impl<T, void, Args...> {}; 

Jonathan's way भी बिल्कुल ठीक है, लेकिन यह उपयोगी नहीं हो सकता है अगर आप अधिक विशेषज्ञताओं है कि प्रत्येक कई पर निर्भर जोड़ना चाहते हैं शर्तों को।

+0

मैंने 'ए ए 'घोषित करने का प्रयास किया, लेकिन संकलक ने मुझे बताया:" अपरिभाषित टेम्पलेट का निहित तत्काल विस्तार :: A_impl '। अगर आप इसे थोड़ा सा समझा सकते हैं तो मैं इसकी बहुत सराहना करता हूं। (क्षमा करें, मैं अभी भी इन चीजों को सीख रहा हूं) – astroboylrx

+0

@astroboylrx इसके लिए काम करने वाला पहला 'ए' की टेम्पलेट पैरामीटर सूची में टाइप करें' मान 'सदस्य होने की आवश्यकता है, क्योंकि 'enable_if' में चेक इस पर निर्भर करता है। आपने इसके बजाय' float' का उपयोग किया है। 'value' सदस्य के बिना,' enable_if' में चेक अमान्य हैं, इसलिए 'A_impl' का प्राथमिक टेम्पलेट (इसमें कोई कार्यान्वयन नहीं है, इसे केवल घोषित किया गया है) चुना जाता है और आपको त्रुटि मिलती है। – jrok

+0

मेरे देर के उत्तर के लिए खेद है। इस स्पष्टीकरण के लिए धन्यवाद। मुझे अब दिख रहा है। :-) – astroboylrx

9

यह है जैसे कि अपने उद्देश्यों के लिए आप सक्षम/वर्ग को निष्क्रिय करने की जरूरत नहीं है, तो आप सिर्फ एक आंशिक विशेषज्ञता की जरूरत है दिखता है:

template <typename T, bool B = T::value, typename... Args> 
    class A; 

template <typename T, typename... Args> 
    class A<T, true, Args...>; 

template <typename T, typename... Args> 
    class A<T, false, Args...>; 
+1

तो जब आप 'Args' प्रदान करते हैं तो आपको मैन्युअल रूप से 'B' प्रदान करना होगा ... – Jarod42

+3

मुझे लगता है कि [टेम्पलेट उपनाम का उपयोग करना] यहां क्लिक करें (http://coliru.stacked-crooked.com/a/524efebedc6a4d1c) ओपी चाहता है कि –

+0

हां, तो यह आसान है कि इसे अधिक उपयोगकर्ता के अनुकूल बनाने के लिए उपनाम में –

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