इस कोड को सबसे compilers में संकलित करने के लिए विफल रहता है, लेकिन पहली बार में मैं सहज उम्मीद SFINAE मुझे की रक्षा के लिए:SFINAE, कटौती बनाम इन्स्टेन्शियशन
:
typedef void (*A)();
template < typename T >
struct a_metafun { typedef typename T::type type; };
template < typename T >
typename a_metafun<T>::type f(T) {}
template < typename T>
void f(T(*)()) {}
int main() { f(A()); }
मैं कम से कम दो तरीकों से इस समस्या को ठीक कर सकते हैं
template < typename T > typename T::type f(T) {}
2) को परिभाषित "a_metafun" ऐसी है कि वह टी का विश्लेषण करती है और प्रकार होता है, तो टी से एक है और मैं नहीं करता है: 1) करने के लिए) की "metafun" च (परिभाषा बदलें वास्तव में क्या स्थिति SFINAE लागू कर सकते हैं के तहत 14.8.2 (सी ++ 03) को देख पर
BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
typedef < template T, bool = has_type<T>::value >
struct a_metafun { };
typedef < template T >
struct a_metafun<T, true> { typedef typename T::type type };
यह मेरे लिए लग रहा है जैसे कि यह निर्दिष्ट करता है: च यह नहीं है ... लेकिन बिना किसी त्रुटि के किसी भी तरह को दर्शाता है। क्या देखने के लिए कोई बेहतर जगह है? पहले से ही कट किए गए टेम्पलेट के तत्कालता में विफलता, किसी अन्य की कटौती के दौरान भी, इस सूची में शामिल नहीं लगती है।
एक और दिशा जिसे मैंने यह अवैध बनाने के लिए लिया है, यह है कि a_metafun की कटौती पहले ही हो चुकी है और इसके अंदरूनी हिस्सों का त्वरण त्रुटि उत्पन्न कर रहा है। SFINAE तत्काल के दौरान लागू नहीं होता है लेकिन केवल कटौती के दौरान, या क्या मैं वहां गलत हूं? हालांकि, दूसरे मामले में, a_metafun सही ढंग से किया जा रहा है, और अच्छी तरह से गठित किया गया है लेकिन इसमें बस "टाइप" परिभाषा नहीं है, जिसका अर्थ है कि इसे चालू करने का प्रयास करने वाला टेम्पलेट प्रतिस्थापन के कारण विफल रहा है।
असल में मैं सोच रहा हूं कि मानक में क्या व्यवहार देख रहा है, जो मैं देख रहा हूं। प्रत्येक कंपाइलर मैंने शिकायत की कोशिश की है, यहां तक कि आओ। मेरा मानना है कि वे ऐसा करने में सही हैं, मैं पूरी तरह से क्यों नहीं जानता हूं कि क्यों।
तो, विशेषज्ञ ... क्या है? प्रकार की तात्कालिकता, एफ() में कटौती के संदर्भ में भी एसएफआईएनएई बहिष्करण के बजाय त्रुटि का कारण बनती है?
मुझे लगता है कि सी ++ 11 में असफल चाहिए, सी ++ 03 यद्यपि में नहीं: यहाँ एक सक्रिय मुद्दा है। SFINAE नियम (या बल्कि * शब्द *) सी ++ 11 में थोड़ा बदल गया है। – Nawaz