2017-08-15 19 views
6

मैं एक परियोजना एक टेम्पलेट समारोह के रूप में तो है, जिस पर काम कर रहा हूँ पर संकलन विफल:मेक सी ++ टेम्पलेट समारोह के विशिष्ट इन्स्टेन्शियशन

template <class T> 
T foo<T>(T val) { return someFunc(val); } 

template <> 
bool foo<bool>(bool val) { return otherFunc(val); }; 

अब, मैं एक वर्ग Bar है, जो मैं नहीं करना चाहते इनपुट के रूप में स्वीकार करें। असल में, मैं चाहता हूं कि यह संकलन त्रुटि स्पॉट करने में आसान हो। समस्या यह है कि अगर मैं ऐसा करता हूं:

template <> 
Bar foo<Bar>(Bar val) { static_assert(false,"uh oh..."); } 

यह प्रत्येक संकलन पर विफल रहता है। मुझे https://stackoverflow.com/a/3926854/7673414 मिला, जो कहता है कि मुझे टेम्पलेट प्रकार का संदर्भ देना होगा, अन्यथा स्थैतिक जोर हमेशा होता है। समस्या यह है कि मेरे पास टेम्पलेट प्रकार नहीं है। यदि मैं करता हूं:

template< typename T > 
struct always_false { 
    enum { value = false }; 
}; 

template <> 
Bar foo<Bar>(Bar val) { static_assert(always_false<Bar>::value,"uh oh..."); } 

तो यह हमेशा संकलन में विफल रहता है। क्या यह सुनिश्चित करने का कोई तरीका है कि Bar टाइप किए गए टेम्पलेट का एक क्षण हमेशा संकलन त्रुटि का कारण बनता है?

उत्तर

18

foo के बाद से एक पूरी विशेषज्ञता है, यह हमेशा संकलित हो जाएगी, और स्थिर ज़ोर हमेशा कहा जाता हो जाएगा है।

हालांकि, वहाँ है एक easier way:

template <> 
Bar foo<Bar>(Bar val) = delete; 

यह कहेंगे कि इस विशिष्ट संस्करण हटा दी जाती है, और नहीं कहा जा सकता।

+0

यह अच्छा है लेकिन मैं सभी विभिन्न सी-टोर को हटाने के बजाय डी-टोर को हटा दूंगा। –

+1

@YhezkelB। यह एक फ़ंक्शन टेम्पलेट है, क्लास टेम्पलेट नहीं। आप केवल कन्स्ट्रक्टर और विनाशकों के लिए, फ़ंक्शन टेम्पलेट विशेषज्ञता को हटा सकते हैं। –

2

आप अपनी आवश्यकता के अनुसार std::is_same का उपयोग कर सकते हैं।

template <class T> 
T foo<T>(T val) 
{ 
    // Make sure T is not Bar 
    static_assert(std::is_same<T, Bar>::value == false, "uh oh..."); 
    return someFunc(val); 
} 
+1

पर उपलब्ध है? –

+0

@FengWang, किया। इस पर ध्यान दिलाने के लिए धन्यवाद। –

3

एक और तरीका है ही अगर आप किस प्रकार सी ++ 14 उपयोग कर सकते हैं से Bar

template <class T> 
typename std::enable_if< ! std::is_same<T, Bar>::value, T>::type foo<T>(T val) 
{ return someFunc(val); } 

अलग है टेम्पलेट (विशेष नहीं संस्करण) सक्षम है, का उपयोग करते हुए सरल किया जा सकता है std::enable_if_t

template <class T> 
std::enable_if_t< ! std::is_same<T, Bar>::value, T> foo<T>(T val) 
{ return someFunc(val); } 
1

आप C++ 17 का उपयोग कर रहे हैं, तो आप सब कुछ एक साथ constexpr if साथ रख सकते हैं:

template< typename T > 
auto foo(T val) 
{ 
    static_assert(!std::is_same_v<T,Bar>); 

    if constexpr(std::is_same_v<T,bool>) 
    { 
     return other_func(val); 
    } 
    else 
    { 
     return some_func(val); 
    } 

} 

तब आप टेम्पलेट विशिष्ट तत्कालता की संकलन विफलता के दर्द के बिना पहली पंक्ति में static_assert कर सकते हैं।

एक लाइव उदाहरण आप कृपया याद आ रही `)` के लिए `static_assert` जोड़ना होगा https://wandbox.org/permlink/PpR6G0gcvMRoxhhZ

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