2016-08-08 14 views
5

अतीत में निर्माता भार के चयन करने के लिए SFINAE का उपयोग कर, मैं आम तौर पर निम्न का इस्तेमाल किया है:SFINAE काम के लिए इलिप्स का उपयोग कैसे करता है?

template <typename T> 
class Class { 
public: 
    template <typename U = T, typename std::enable_if<std::is_void<U>::value, int>::type=0> 
    Class() { 
     std::cout << "void" << std::endl; 
    } 

    template <typename U = T, typename std::enable_if<!std::is_void<U>::value, int>::type=0> 
    Class() { 
     std::cout << "not void" << std::endl; 
    } 
}; 

हालांकि, मैं सिर्फ इस विकल्प भर में आया था:

template <typename U = T, typename std::enable_if<std::is_void<U>::value>::type...> 
Class() { 
    std::cout << "void" << std::endl; 
} 

यह देखते हुए कि निम्नलिखित गैर कानूनी है। ..

template <typename U = T, void...> // ERROR! 
Class() { } 

... गैर-प्रकार के टेम्पलेट तर्क के बजाए लंबवत विकल्प का उपयोग कैसे किया जाता है?


पूर्ण कोड: http://coliru.stacked-crooked.com/a/64a1aaf13ce6099b

+0

@peppe लेकिन 'टेम्पलेट <टाइपनाम यू = टी, शून्य>' अवैध भी है। क्या किसी प्रकार पैरामीटर के लिए डिफ़ॉल्ट तर्क के रूप में 'शून्य' का उपयोग करने की आवश्यकता नहीं होगी? जैसा कि, 'टेम्पलेट <टाइपनाम यू = टी, टाइपनाम वी = std :: enable_if <...> :: टाइप> '? – zennehoy

+1

@peppe टेम्पलेट के रूप में * प्रकार * पैरामीटर, टेम्पलेट गैर-प्रकार पैरामीटर के रूप में नहीं। – Barry

+0

@ बैरी: IOW 'टेम्पलेट :: टाइप>' गैरकानूनी है क्योंकि यह 'शून्य' को कम करेगा यदि 'शर्त 'सत्य है, क्योंकि यह एक गैर-प्रकार पैरामीटर है, जबकि' टेम्पलेट :: type> 'कानूनी है? – peppe

उत्तर

1

मेरे पिछले जवाब गलत था। माफ़ कीजिये। मैं बस इसे ठीक करने जा रहा हूँ।


इस घोषणा:

template <typename U = T, void...> 
Class() { } 

का उल्लंघन करती है [temp.res]/8:

कार्यक्रम बीमार बनाई है, कोई निदान के लिए आवश्यक है, अगर [...] एक वैरिएडिक टेम्पलेट के प्रत्येक वैध विशेषज्ञता के लिए एक खाली टेम्पलेट पैरामीटर पैक

यह कोई निदान आवश्यक नहीं है, लेकिन संकलक वैसे भी जारी करने का विकल्प चुनता है। किसी भी तरह से, कोड खराब गठित है।

दूसरी ओर

template <typename U = T, std::enable_if_t<std::is_void<U>::value>...> 
Class() { } 

इस आवश्यकता का उल्लंघन नहीं करता। हमारे पास एक खाली पैक है, इसलिए हम इस तथ्य से दूर नहीं जाते कि आप गैर-प्रकार के टेम्पलेट पैरामीटर के रूप में void का उपयोग नहीं कर सकते हैं। इसके अतिरिक्त, enable_if का एक काल्पनिक विशेषज्ञता एक प्रकार प्रदान कर सकता है जो void नहीं है, इसलिए यह उपरोक्त सीमा के कारण बीमार नहीं है।

+0

मैंने 'enable_if_t <..., int>' के साथ कोड का परीक्षण किया है और क्लैंग भी संदिग्ध होने के लिए 'कक्षा 2 ' और 'कक्षा 2 ' दोनों पर आरोप लगाकर संकलित नहीं करता है। यकीन नहीं है कि अगर क्लैंग सही है ... –

+1

@ डब्ल्यूएफ। ट्रंक आईआईआरसी पर तय एक ज्ञात बग है। –

+0

@zennehoy मुझे पता है कि आपने पहले से ही मेरा जवाब स्वीकार कर लिया है, लेकिन मुझे पूरा यकीन नहीं है कि यह गलत था इसलिए मैंने इसे बदल दिया। माफ़ कीजिये। – Barry

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