दिलचस्प पोस्ट
कैसे जीसीसी में गतिशील पुस्तकालय में स्थैतिक पुस्तकालय को लिंक करना ऐरे इनिशियलाइज़ेशन सिंटैक्स जब घोषणा में नहीं है जावा का अर्रे अनुक्रमणिका कहाँ है? Windows पर msysgit के साथ एक Git सर्वर सेटअप करें जावास्क्रिप्ट में वर्तमान यूआरएल प्राप्त करें? मूल प्रक्रिया को मार दिया जाता है जब बाल प्रक्रिया को मार डालो लंबे पूर्णांक के लिए अधिकतम मान दो तिथियों के बीच कार्य दिवसों की संख्या खोजने के लिए MySQL फ़ंक्शन SQL सर्वर: गलत संस्करण 661 संलग्न करें एएसपी.नेट पहचान डीबीसीटीएक्सटीक्स भ्रम नोटपैड ++ में रिक्त स्थान पर टैब परिवर्तित करें मेरा संकेत / स्लॉट कनेक्शन काम नहीं करता है दृश्य स्टूडियो में धीमा डीबगिंग समस्या कुंजी वस्तु (और इसके विपरीत) के लिए जावा ऑब्जेक्ट (बीन) को कैसे परिवर्तित करें? एक ही कुंजी का योग सरणी मान

"अभिव्यक्ति SFINAE" क्या है?

Http://blogs.msdn.com/b/vcblog/archive/2011/09/12/1020929.aspx पर , वीसी ++ टीम आधिकारिक तौर पर घोषित करती है कि उन्होंने अभी तक सी ++ 11 कोर फीचर "अभिव्यक्ति एसएफआईएनएई" को लागू नहीं किया है। हालांकि, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html से निम्न कोड उदाहरणों को कॉपी किया गया है जो वीसी ++ कंपाइलर द्वारा स्वीकार किए जाते हैं।

उदाहरण 1:

template <int I> struct A {}; char xxx(int); char xxx(float); template <class T> A<sizeof(xxx((T)0))> f(T){} int main() { f(1); } 

उदाहरण 2:

 struct X {}; struct Y { Y(X){} }; template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); // #1 X f(Y, Y); // #2 X x1, x2; X x3 = f(x1, x2); // deduction fails on #1 (cannot add X+X), calls #2 

मेरा प्रश्न यह है कि "अभिव्यक्ति SFINAE" क्या है?

वेब के समाधान से एकत्रित समाधान ""अभिव्यक्ति SFINAE" क्या है?"

अभिव्यक्ति एसएफआईएनएई को आपके द्वारा लिंक किए गए पेपर में बहुत अच्छा समझाया गया है, मुझे लगता है। यह अभिव्यक्ति पर SFINAE है यदि decltype भीतर अभिव्यक्ति मान्य नहीं है, तो ठीक है, कार्य को decltype के वीआईपी लाउंज से लात decltype । आप इस उत्तर के अंत में मानक शब्दों को पा सकते हैं।

वीसी ++ पर एक नोट: उन्होंने इसे पूरी तरह से लागू नहीं किया। साधारण अभिव्यक्ति पर, यह काम कर सकता है, लेकिन दूसरों पर, यह नहीं होगा उन उदाहरणों के लिए इस उत्तर पर टिप्पणियों में एक चर्चा देखें, जो असफल हों। इसे सरल बनाने के लिए, यह काम नहीं करेगा:

 #include <iostream> // catch-all case void test(...) { std::cout << "Couldn't call\n"; } // catch when C is a reference-to-class type and F is a member function pointer template<class C, class F> auto test(C c, F f) -> decltype((c.*f)(), void()) // 'C' is reference type { std::cout << "Could call on reference\n"; } // catch when C is a pointer-to-class type and F is a member function pointer template<class C, class F> auto test(C c, F f) -> decltype((c->*f)(), void()) // 'C' is pointer type { std::cout << "Could call on pointer\n"; } struct X{ void f(){} }; int main(){ X x; test(x, &X::f); test(&x, &X::f); test(42, 1337); } 

रेशम के साथ, यह अपेक्षित आउटपुट देता है:

संदर्भ के साथ कॉल कर सकते हैं
सूचक के साथ कॉल कर सकते हैं
कॉल नहीं किया जा सका

एमएसवीसी के साथ, मुझे मिल … अच्छा, एक कंपाइलर त्रुटि:

 1> src \ main.cpp (20): त्रुटि C2995: '' अज्ञात-प्रकार 'परीक्षण (सी, एफ)': फ़ंक्शन टेम्पलेट पहले ही परिभाषित किया गया है
 1> src \ main.cpp (11): 'टेस्ट' की घोषणा देखें

यह भी लगता है कि जीसीसी 4.7.1 कार्य के ऊपर काफी नहीं है:

 source.cpp: 'टेम्पलेट decltype के प्रतिस्थापन में ((सी। * एफ), शून्य ())) परीक्षा (सी, एफ) [सी = एक्स * के साथ;  एफ = शून्य (एक्स :: *) ()] ':
 source.cpp: 29: 17: यहां से आवश्यक है
 source.cpp: 11: 6: त्रुटि: सदस्य पॉइंटर 'एफ' को 'सी' में लागू नहीं किया जा सकता, जो कि गैर-वर्ग प्रकार 'X *' का है
 source.cpp: 'टेम्पलेट decltype के प्रतिस्थापन में ((c। * f (), शून्य ())) परीक्षा (सी, एफ) [सी के साथ = int;  F = int] ':
 source.cpp: 30: 16: यहां से आवश्यक है
 source.cpp: 11: 6: त्रुटि: सदस्य फलक के रूप में 'f' का उपयोग नहीं किया जा सकता, क्योंकि यह 'int' प्रकार है

अभिव्यक्ति SFINAE का एक सामान्य उपयोग तब होता है जब गुणों को परिभाषित करते हैं, जैसे क्लास किसी विशिष्ट सदस्य फ़ंक्शन को देखता है या नहीं:

 struct has_member_begin_test{ template<class U> static auto test(U* p) -> decltype(p->begin(), std::true_type()); template<class> static auto test(...) -> std::false_type; }; template<class T> struct has_member_begin : decltype(has_member_begin_test::test<T>(0)) {}; 

लाइव उदाहरण (जो आश्चर्यजनक रूप से जीसीसी 4.7.1 पर फिर से काम करता है।)

यह भी मेरा जवाब देखें, जो एक अन्य तकनीक (तकनीक के बिना उर्फ) में एक ही तकनीक का उपयोग करता है।


सामान्य शब्दों:

§14.8.2 [temp.deduct]

p6 टेम्पलेट अर्गलमेंट कटौती प्रक्रिया में कुछ बिंदुओं पर एक फ़ंक्शन प्रकार लेने के लिए आवश्यक है जो कि टेम्पलेट पैरामीटर का उपयोग करता है और उन टेम्पलेट पैरामीटरों को संबंधित टेम्पलेट तर्कों के साथ प्रतिस्थापित करता है। यह टेम्पलेट अर्गलमेंट कटाव की शुरुआत में किया जाता है, जब किसी भी स्पष्ट रूप से निर्दिष्ट टेम्पलेट तर्क फ़ंक्शन प्रकार में प्रतिस्थापित होते हैं, और फिर टेम्प्लेट तर्क कटाव के अंत में जब कोई भी तर्क तर्क जो डिफ़ॉल्ट तर्कों से अनुमानित या प्राप्त किया जाता है, प्रतिस्थापित किया जाता है

p7 प्रतिस्थापन सभी प्रकार और अभिव्यक्ति में होता है जिसका उपयोग फ़ंक्शन प्रकार और टेम्प्लेट पैरामीटर घोषणाओं में किया जाता है। अभिव्यक्ति में केवल निरंतर अभिव्यक्ति नहीं होती है जैसे कि सरणी सीमाओं में या नॉनटाइप टेम्प्लेट तर्क के रूप में प्रकट होते हैं, लेकिन sizeof भीतर सामान्य अभिव्यक्ति (उदा।, निरंतर अभिव्यक्ति), decltype और अन्य संदर्भों में गैर-निरंतर अभिव्यक्तियां शामिल होती हैं।

p8 यदि प्रतिस्थापन एक अमान्य प्रकार या अभिव्यक्ति में परिणाम होता है, तो कटौती विफल हो जाती है। एक अमान्य प्रकार या अभिव्यक्ति वह है जो बदली हुई आर्गुमेंट्स का उपयोग करके लिखी गई हो। […]