दिलचस्प पोस्ट
सी क्यों नहीं है अस्वाभाविक फ़्लोट्स? देखें का चयन FROM खंड में एक subquery शामिल है मैं iPhone पर प्रोग्राम को एक छवि कैसे दिखाऊंगा? टीएमपी: वेक्टर्स का कार्टेशियन उत्पाद को कैसे सामान्य बनाना है? WPF डेटाग्रिड में दिनांक स्वरूपण में या एसक्यूएल WHERE खंड में डोम समाप्त होने के बाद मैं एक निर्देश कैसे चला सकता हूं? ईवेंट को चालू ब्राउज़र पर कैप्चर करें चार्ट.जेएस v2: टूलटिप्स हमेशा पाई चार्ट पर कैसे दिखें? सिस्टम में मॉनिटर प्रोसेस प्रारंभ करें बेलिल के साथ पारदर्शी ES6 कक्षाओं के लिए मिक्सिन्स सी # .NET में App.config क्या है? इसका इस्तेमाल कैसे करें? आदिम डेटा प्रकारों के लिए अशक्त हमें म्यूट एक्स का उपयोग कब करना चाहिए और हमें सैकॉफ का उपयोग कब करना चाहिए बंडलों का उपयोग करते हुए एंड्रॉइड गतिविधियों के बीच आप छवियों (बिटमैप) को कैसे पारित करते हैं?

SFINAE वापसी प्रकार में काम कर रहा है लेकिन टेम्पलेट पैरामीटर के रूप में नहीं

मैंने पहले से ही कई बार std::enable_if<> मुहावरे का इस्तेमाल किया है और मुझे वापसी के प्रकारों की बजाय टेम्पलेट मापदंडों में अपना std::enable_if<> डालने के लिए इस्तेमाल हुआ। हालांकि, मुझे कुछ तुच्छ मामलों में पता चला था जहां यह काम नहीं कर रहा था, और मुझे यकीन नहीं है कि क्यों सबसे पहले, यह मेरा मुख्य है:

 int main() { foo(5); foo(3.4); } 

यहां foo कार्यान्वयन है जो त्रुटि को ट्रिगर करता है:

 template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> auto foo(T) -> void { std::cout << "I'm an integer!\n"; } template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type> auto foo(T) -> void { std::cout << "I'm a floating point number!\n"; } 

और यहां कोड के एक अनुमान के बराबर टुकड़ा है जो ठीक काम करता है:

 template<typename T> auto foo(T) -> typename std::enable_if<std::is_integral<T>::value>::type { std::cout << "I'm an integrer!\n"; } template<typename T> auto foo(T) -> typename std::enable_if<std::is_floating_point<T>::value>::type { std::cout << "I'm a floating point number!\n"; } 

मेरा प्रश्न यह है कि: foo के पहले कार्यान्वयन से उस त्रुटि को ट्रिगर क्यों होता है, जबकि दूसरा कोई इसे ट्रिगर नहीं करता?

 main.cpp:14:6: error: redefinition of 'template<class T, class> void foo(T)' auto foo(T) ^ main.cpp:6:6: note: 'template<class T, class> void foo(T)' previously declared here auto foo(T) ^ main.cpp: In function 'int main()': main.cpp:23:12: error: no matching function for call to 'foo(double)' foo(3.4); ^ main.cpp:6:6: note: candidate: template<class T, class> void foo(T) auto foo(T) ^ main.cpp:6:6: note: template argument deduction/substitution failed: main.cpp:5:10: error: no type named 'type' in 'struct std::enable_if<false, void>' typename = typename std::enable_if<std::is_integral<T>::value>::type> ^ 

संपादित करें :

कार्य कोड और दोषपूर्ण कोड ।

Solutions Collecting From Web of "SFINAE वापसी प्रकार में काम कर रहा है लेकिन टेम्पलेट पैरामीटर के रूप में नहीं"

आपको 14.5.6.1 Function template overloading (सी 14.5.6.1 Function template overloading 11 मानक) पर एक नज़र रखना चाहिए जहां फ़ंक्शन टेम्प्लेट्स समानता को परिभाषित किया गया है। संक्षेप में, डिफ़ॉल्ट टेम्पलेट तर्कों को नहीं माना जाता है, इसलिए 1 मामले में आपके पास एक ही फ़ंक्शन टेम्पलेट दो बार परिभाषित किया गया है। दूसरे मामले में आपको वापसी प्रकार में उपयोग किए गए टेम्प्लेट पैरामीटर का जिक्र है (फिर से 14.5.6.1/4 देखें)। चूंकि यह अभिव्यक्ति हस्ताक्षर का हिस्सा है, इसलिए आपको दो अलग फ़ंक्शन टेम्पलेट घोषणाएं प्राप्त होती हैं और इस प्रकार SFINAE को काम करने का मौका मिलता है।

टेम्पलेट का = ... सिर्फ एक डिफ़ॉल्ट पैरामीटर देता है यह वास्तविक हस्ताक्षर का हिस्सा नहीं है जो दिखता है

 template<typename T, typename> auto foo(T a); 

दोनों कार्यों के लिए

आपकी आवश्यकताओं के आधार पर, इस समस्या का सबसे सामान्य समाधान टैग डिस्पैचिंग का उपयोग कर रहा है।

 struct integral_tag { typedef integral_tag category; }; struct floating_tag { typedef floating_tag category; }; template <typename T> struct foo_tag : std::conditional<std::is_integral<T>::value, integral_tag, typename std::conditional<std::is_floating_point<T>::value, floating_tag, std::false_type>::type>::type {}; template<typename T> T foo_impl(T a, integral_tag) { return a; } template<typename T> T foo_impl(T a, floating_tag) { return a; } template <typename T> T foo(T a) { static_assert(!std::is_base_of<std::false_type, foo_tag<T> >::value, "T must be either floating point or integral"); return foo_impl(a, typename foo_tag<T>::category{}); } struct bigint {}; template<> struct foo_tag<bigint> : integral_tag {}; int main() { //foo("x"); // produces a nice error message foo(1); foo(1.5); foo(bigint{}); } 

टेम्प्लेट में मान काम करते हैं:

 template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> auto foo(T) -> void { std::cout << "I'm an integer!\n"; } template<typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0> auto foo(T) -> void { std::cout << "I'm a floating point number!\n"; }