मैं सी ++ टेम्पलेट का चयन करने के तरीके को समझने की कोशिश कर रहा हूं।सदस्य फ़ंक्शन टेम्पलेट चयन और SFINAE
template <typename R>
class Curious
{
public:
template <typename T, typename std::enable_if<std::is_const<T>::value, int>::type = 33>
void test1() {}
template <typename T, typename std::enable_if<!std::is_const<T>::value, int>::type = 33>
void test1() {}
template <typename T, typename = typename std::enable_if<std::is_const<T>::value>::type>
void test2() {}
template <typename T, typename = typename std::enable_if<!std::is_const<T>::value>::type>
void test2() {}
template <typename std::enable_if<std::is_const<R>::value>::type * = nullptr>
void test3() {}
template <typename std::enable_if<!std::is_const<R>::value>::type * = nullptr>
void test3() {}
// works
template <typename T = void>
typename std::enable_if<std::is_const<R>::value, T>::type test4() {}
template <typename T = void>
typename std::enable_if<!std::is_const<R>::value, T>::type test4() {}
// also works
template <typename T = void, typename std::enable_if<std::is_const<R>::value, T>::type * = nullptr>
void test5() {}
template <typename T = void, typename std::enable_if<!std::is_const<R>::value, T>::type * = nullptr>
void test5() {}
}; // Curious
पहले दो कार्य (test1) ठीक से काम (क्यों?):
Curious<int> curious;
curious.test1<int>();
curious.test1<const int>();
जबकि संकलन त्रुटियों कारण उनमें से बाकी अर्थात्, निम्नलिखित कोड नमूना पर विचार करें। संकलक दावों मैं एक नकली बनाने के लिए कोशिश कर रहा हूँ test2 समारोह के बारे में:
error C2535: 'void Curious::test2(void)': member function already defined or declared
Here प्रलेखन कहते हैं:
एक आम गलती दो समारोह टेम्पलेट्स है कि केवल में मतभेद घोषित करने के लिए है उनके डिफ़ॉल्ट टेम्पलेट तर्क। यह अवैध है क्योंकि डिफ़ॉल्ट टेम्पलेट तर्क फ़ंक्शन टेम्पलेट के हस्ताक्षर का हिस्सा नहीं हैं, और एक ही हस्ताक्षर के साथ दो अलग-अलग फ़ंक्शन टेम्पलेट्स घोषित करना अवैध है।
तो ऐसा लगता है। हालांकि, मुझे पहले दो कार्यों से बहुत अंतर दिखाई नहीं देता है, जिसमें डिफ़ॉल्ट टेम्पलेट तर्क भी है। इस प्रकार हमारे पास डिफ़ॉल्ट मान (test1 - works) के विरुद्ध एक डिफ़ॉल्ट प्रकार (test2 - काम नहीं करता) है। क्या इसके बारे में कोई नियम है?
test3:
error C2039: 'type': is not a member of 'std::enable_if'के मामले में पहली बार इस तरह के सदस्य फ़ंक्शन टेम्पलेट में डिफ़ॉल्ट गैर-प्रकार पैरामीटर होता है, लेकिन यह क्लास टेम्पलेट पैरामीटर पर निर्भर करता है। अब SFINAE गलत को छोड़ नहीं देता है (यह भी सुनिश्चित नहीं है)।
चौथे मामले में SFINAE रिटर्न प्रकार से टेम्पलेट को हल करता है। लेकिन क्या इन test4 कार्यों में समान हस्ताक्षर नहीं है? क्योंकि वे केवल रिटर्न प्रकार में भिन्न होते हैं।
जहां तक मैं समझता हूं, पांचवें मामले में अतिरिक्त पैरामीटर जोड़ना फ़ंक्शन टेम्पलेट पैरामीटर पर test5 हस्ताक्षर निर्भर करता है, इसलिए SFINAE में और रिज़ॉल्यूशन काम करता है।
मैं इस टेम्पलेट्स के साथ सी ++ सौदों के बारे में काफी उलझन में हूं। क्या कोई इन चीज़ों को साफ़ करने के लिए बहुत दयालु हो सकता है?
एक नोट के रूप में, के बाद से सी ++ 14, आप की जगह ले सकती 'typename std :: enable_if :: type'' std :: enable_if_t 'द्वारा। –
Jarod42