यदि आपको किसी ऐसी चीज़ की ज़रूरत है जो फ़ंक्शन कॉल जैसी कोई चीज़ नहीं है, तो std::result_of
बस लागू नहीं होती है। decltype()
आप किसी भी अभिव्यक्ति का प्रकार दे सकते हैं।
यदि हम एक फ़ंक्शन कॉल (बीच std::result_of_t<F(Args...)>
और decltype(std::declval<F>()(std::declval<Args>()...)
) के रिटर्न प्रकार को निर्धारित करने के केवल विभिन्न तरीकों से खुद को प्रतिबंधित करते हैं , तो एक अंतर है।
std::result_of<F(Args...)
की तरह परिभाषित किया गया है:
यदि अभिव्यक्ति
INVOKE (declval<Fn>(), declval<ArgTypes>()...)
को अच्छी तरह से बनाया जाता है, जब एक अनवैलेंटेड ऑपरेंड (क्लाज 5) के रूप में माना जाता है, तो सदस्य टाइप किए गए प्रकार का नाम decltype(INVOKE (declval<Fn>(), declval<ArgTypes>()...));
अन्यथा होगा, कोई सदस्य प्रकार नहीं होगा।
के बीच का अंतर result_of<F(Args..)>::type
और decltype(std::declval<F>()(std::declval<Args>()...)
वह सब है INVOKE
। का उपयोग करना declval
/ decltype
सीधे, टाइप करने के लिए काफी लंबा होने के अलावा, केवल तभी मान्य है यदि F
सीधे कॉल करने योग्य है (एक फ़ंक्शन ऑब्जेक्ट प्रकार या फ़ंक्शन या फ़ंक्शन पॉइंटर)। result_of
इसके अतिरिक्त सदस्यों के कार्यों के लिए संकेत और सदस्य डेटा के लिए संकेत का समर्थन करता है।
प्रारंभ में, SFINAE के अनुकूल अभिव्यक्ति का उपयोग declval
/ decltype
गारंटी, जबकि std::result_of
कटौती की विफलता के बजाय आपको एक कठिन त्रुटि दे सकती है। इसे C ++ 14 में सही किया गया है: std::result_of
अब SFINAE के अनुकूल होना आवश्यक है ( इस पेपर के लिए धन्यवाद )।
तो एक अनुरूप C ++ 14 संकलक पर, std::result_of_t<F(Args...)>
सख्ती से बेहतर है। यह स्पष्ट, छोटा है, और सही ढंग से † का समर्थन करता है और अधिक F
रों ‡ ।
That जब तक कि, आप इसे एक ऐसे संदर्भ में उपयोग कर रहे हैं जहाँ आप सदस्यों को संकेत देने की अनुमति नहीं देना चाहते हैं, तो
std::result_of_t
ऐसे मामले में सफल होंगे जहाँ आप चाहते हैं कि यह विफल हो जाए।
Ions अपवादों के साथ। यदि यह सदस्यों को पॉइंटर्स का समर्थन करता है, result_of
तो यदि आप एक अमान्य प्रकार-आईडी को तत्काल करने का प्रयास करते हैं तो यह काम नहीं करेगा । इनमें एक फ़ंक्शन को वापस करना या मूल्य के अनुसार सार प्रकार लेना शामिल होगा। पूर्व .:
template <class F, class R = result_of_t<F()>>
R call(F& f) { return f(); }
int answer() { return 42; }
call(answer); // nope
सही उपयोग हुआ होगा result_of_t<F&()>
, लेकिन यह एक ऐसा विवरण है जिसे आपको याद नहीं रखना है decltype
।
decltype
यह बदसूरत है, लेकिन अधिक शक्तिशाली भी है।result_of
केवल उन प्रकारों के लिए उपयोग किया जा सकता है जो कॉल करने योग्य हैं और उन्हें तर्क के रूप में प्रकारों की आवश्यकता होती है। उदाहरण के लिए, आपresult_of
यहां उपयोग नहीं कर सकते हैं:template <typename T, typename U> auto sum( T t, U u ) -> decltype( t + u );
यदि तर्क अंकगणितीय प्रकार हो सकते हैं (ऐसा कोई कार्य नहीं हैF
जिसे आपF(T,U)
प्रतिनिधित्व करने के लिए परिभाषित करते हैंt+u
। उपयोगकर्ता परिभाषित प्रकारों के लिए जो आप कर सकते हैं। उसी तरह से (मैं वास्तव में इसके साथ नहीं खेला है) मैं कल्पना करता हूं। सदस्य विधियों को कॉल करने के लिएresult_of
बाइंडरों या