दिलचस्प पोस्ट
त्रुटियों पर बैकस्ट्र्रेस बनाने के लिए मैं PHP कैसे प्राप्त कर सकता हूं? डेल्फी में 'परिणाम' का डिफ़ॉल्ट मान क्या है? विशिष्ट यूआरएल खोलने के लिए ब्राउजर पर एक इरादा भेजना कैसे पता कैसे एक मूल DLL फ़ाइल x64 या x 86 के रूप में संकलित किया गया है? मैं डॉकर कंटेनर के लिए पर्यावरण चर कैसे पार करूं? बहुरूपता, ओवरलोडिंग और समान अवधारणाओं को ओवरराइड कर रहे हैं? क्या हमें * सापेक्ष * त्रुटि के खिलाफ समानता के लिए अस्थायी बिंदु संख्याओं की तुलना करनी चाहिए? पोस्ट मॉडल में वापस मॉडल मॉडल को देखने का नक्शा कैसे करें? Scanf () का उपयोग करके चरित्र इनपुट की समस्याएं क्लास जेएसओएन धारावाहिक बनाने के लिए कैसे करें उल्का सदस्यता संग्रह के क्रमबद्ध क्रम को अपडेट नहीं करता है मैं एक ही प्रकार के दो हॅशमार्क ऑब्जेक्ट्स को कैसे जोड़ सकता हूं? न्यूनतम वैध JSON क्या है? PHP का उपयोग करके पूर्ण यूआरएल में रिश्तेदार पथ को ट्रांसफ़ॉर्म करें PHP में ऑब्जेक्ट के एक विशिष्ट प्रकार की जांच कैसे करें

एसएफआईएनएई के साथ कंटैक्सप्रस का पता लगा रहा है

मैं C ++ 11 में नई कार्यक्षमता का लाभ लेने के लिए कुछ C ++ कोड को अपग्रेड करने पर काम कर रहा हूं मेरे पास एक विशिष्ट वर्ग है, जो कुछ फ़ंक्शंस मूलभूत प्रकारों को लौटते हैं, जो ज्यादातर समय होते हैं, लेकिन हमेशा नहीं, हमेशा निरंतर अभिव्यक्ति वापस करते हैं मैं अलग-अलग काम करना चाहूंगा कि क्या फ़ंक्शन constexpr या नहीं। मैं निम्नलिखित दृष्टिकोण के साथ आया:

 template<typename Trait> struct test { template<int Value = Trait::f()> static std::true_type do_call(int){ return std::true_type(); } static std::false_type do_call(...){ return std::false_type(); } static bool call(){ return do_call(0); } }; struct trait { static int f(){ return 15; } }; struct ctrait { static constexpr int f(){ return 20; } }; int main() { std::cout << "regular: " << test<trait>::call() << std::endl; std::cout << "constexpr: " << test<ctrait>::call() << std::endl; } 

अतिरिक्त int / ... पैरामीटर वहाँ है ताकि अगर दोनों फ़ंक्शन SFINAE के बाद उपलब्ध हों, तो सबसे पहले एक संकल्प को ओवरलोड करके चुना जाता है।

कंपाइल 3.2 शो से संकलित और चल रहा है:

 regular: 0 constexpr: 1 

तो यह काम करने के लिए प्रतीत होता है, लेकिन मैं जानना चाहूंगा कि क्या कोड कानूनी C ++ 11 है विशेष रूप से चूंकि यह मेरी समझ है कि एसएफआईएनएई के नियमों में बदलाव आया है।

Solutions Collecting From Web of "एसएफआईएनएई के साथ कंटैक्सप्रस का पता लगा रहा है"

नोट: मैंने यहां एक प्रश्न खोला है कि क्या ओपी कोड वास्तव में मान्य है। नीचे दिए गए मेरा पुनः लिखित उदाहरण किसी भी मामले में काम करेगा।


लेकिन मैं जानना चाहूंगा कि क्या कोड कानूनी सी ++ 11 है

यह है, हालांकि डिफ़ॉल्ट टेम्पलेट तर्क को थोड़ा असामान्य माना जा सकता है मैं व्यक्तिगत रूप से निम्न शैली को बेहतर ढंग से पसंद करता हूं, जो आप के समान है (पढ़ना: I) फ़ंक्शन के अस्तित्व की जांच करने के लिए एक विशेषता लिखें, बस एक गैर-प्रकार के टेम्प्लेट पैरामीटर का उपयोग करके और decltype को decltype :

 #include <type_traits> namespace detail{ template<int> struct sfinae_true : std::true_type{}; template<class T> sfinae_true<(T::f(), 0)> check(int); template<class> std::false_type check(...); } // detail:: template<class T> struct has_constexpr_f : decltype(detail::check<T>(0)){}; 

लाइव उदाहरण


स्पष्टीकरण समय ~

आपका मूल कोड काम करता है क्योंकि डिफ़ॉल्ट टेम्पलेट तर्क का तत्काल तात्पर्य उसके फ़ंक्शन टेम्पलेट के तात्पर्य का अर्थ है, जिसका अर्थ है, आपके मामले में, main , इसलिए इसे उस से पहले प्रतिस्थापित नहीं किया जा सकता है।

§14.6.4.1 [temp.point] p2

यदि एक फ़ंक्शन टेम्पलेट […] को उस फ़ंक्शन टेम्पलेट के डिफ़ॉल्ट तर्क की परिभाषा का उपयोग करने वाले तरीके से कहा जाता है […], डिफ़ॉल्ट तर्क का तत्काल बिंदु फ़ंक्शन टेम्पलेट के प्रारंभिक बिंदु है [ …]।

उसके बाद, यह सिर्फ सामान्य एसएफआईएनएई नियम है


† कम से कम मुझे लगता है, यह मानक में पूरी तरह से स्पष्ट नहीं है।

@ मार्शल-क्लॉ के द्वारा उठाए गए, मैं एक प्रकार-गुण के कुछ-अधिक-सामान्य संस्करणों को constexpr लिए constexpr । मैंने इसे std::invoke_result पर मॉडलिंग किया है, लेकिन क्योंकि constexpr इनपुट पर निर्भर करता है, टेम्पलेट तर्क में पारित मूल्यों के लिए होते हैं, बजाय प्रकार

यह कुछ हद तक सीमित है, क्योंकि टेम्पलेट एग्री केवल एक सीमित प्रकार के प्रकार हो सकते हैं , और जब वे विधि कॉल में पहुंचते हैं तब वे सभी कॉन्स्ट होते हैं। यदि आप एक संदर्भ पैरामीटर के लिए अन्य प्रकार, या गैर-कॉन्स्ट लैवल्यू की आवश्यकता होती है, तो आप आसानी से एक constexpr रैपर विधि का परीक्षण कर सकते हैं।

वास्तव में उपयोगी कोड की तुलना में व्यायाम और प्रदर्शन का कुछ और हिस्सा।

और template<auto F, auto... Args> का उपयोग template<auto F, auto... Args> यह सी ++ 17-केवल, जीसीसी 7 या क्लैंग की आवश्यकता करता है 4. एमएसवीसी 14.10.25017 इसे संकलित नहीं कर सकता।

 namespace constexpr_traits { namespace detail { // Call the provided method with the provided args. // This gives us a non-type template parameter for void-returning F. // This wouldn't be needed if "auto = F(Args...)" was a valid template // parameter for void-returning F. template<auto F, auto... Args> constexpr void* constexpr_caller() { F(Args...); return nullptr; } // Takes a parameter with elipsis conversion, so will never be selected // when another viable overload is present template<auto F, auto... Args> constexpr bool is_constexpr(...) { return false; } // Fails substitution if constexpr_caller<F, Args...>() can't be // called in constexpr context template<auto F, auto... Args, auto = constexpr_caller<F, Args...>()> constexpr bool is_constexpr(int) { return true; } } template<auto F, auto... Args> struct invoke_constexpr : std::bool_constant<detail::is_constexpr<F, Args...>(0)> {}; } 

उपयोग के साथ लाइव डेमो wandbox पर मामलों