यदि आपको किसी ऐसी चीज़ की ज़रूरत है जो फ़ंक्शन कॉल जैसी कोई चीज़ नहीं है, तो 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बाइंडरों या