2012-01-21 8 views
17

§20.2.4 [declval]'add_rvalue_reference <T> :: प्रकार' और 'टी &&' के संदर्भ में निर्दिष्ट 'अस्वीकरण' क्यों नहीं है?

template <class T> 
typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand 

क्यों यहाँ add_rvalue_reference का उपयोग करें?

§20.9.7.2 [meta.trans.ref] से add_rvalue_reference पर:

तो T नाम एक वस्तु या समारोह प्रकार तो type typedef सदस्य T&& नाम होगा; अन्यथा, type का नाम T होगा। [नोट: यह नियम संदर्भ ढहने के अर्थशास्त्र को दर्शाता है (8.3.2)। उदाहरण के लिए, जब एक प्रकार T एक प्रकार T1& नाम देता है, तो add_rvalue_reference<T>::type टाइप करें एक रावल्यू संदर्भ नहीं है। अंत टिप्पणी]

add_rvalue_reference के बाद से वैसे भी टूट संदर्भ प्रतिबिंबित करने के लिए, क्यों नहीं बस T&& निम्नलिखित की तरह का उपयोग मतलब है?

template<class T> 
T&& declval(); 

क्या गलत हो सकता है? दो संस्करणों के बीच मतभेद क्या हैं?

+1

"संभवतः क्या गलत हो सकता है?" बत्तख! –

+3

@ लाइटनेसरेसेसिन ऑर्बिट: एर .. क्या? सिर्फ इसलिए कि मैंने कुछ अनदेखा किया है -1 मुझे मिल रहा है? दिलचस्प सामान ... – Xeo

+1

@ लाइटनेस अब _that_ व्यर्थ है। –

उत्तर

14

मुझे नहीं पता कि यह वास्तविक कारण है, लेकिन add_rvalue_reference के पास void के लिए अलग-अलग व्यवहार हैं।

add_rvalue_reference<void>::type बस void है।

void&& एक त्रुटि है।

+0

ओह, अच्छा बिंदु। हालांकि, आप वास्तव में 'std :: declval () 'कब चाहते हैं? मैं केवल एक अभिव्यक्ति में कल्पना कर सकता हूं SFINAE 'decltype (t.size(), std :: declval (), std :: true_type) 'या कुछ, लेकिन' शून्य() 'बहुत सुविधाजनक है और यह सब कुछ भी करता है। – Xeo

+1

@Xeo शायद टेम्पलेट कक्षाओं में जो 'शून्य' को टेम्पलेट पैरा के रूप में अनुमति देते हैं? 'टेम्पलेट कक्षा foo {... declval ...}; foo बार; '। यह दुर्लभ हो सकता है, लेकिन यह बेहतर होता है जब आपको इसकी आवश्यकता नहीं होती है, अगर यह आपकी आवश्यकता होने पर काम नहीं करता है। –

+0

मैं इसे स्वीकार करूंगा, क्योंकि यह स्पष्ट रूप से बताता है कि मैं क्या खो रहा था/अनदेखा करता हूं: "' void && 'एक त्रुटि है "। – Xeo

10

कई परिभाषाएं declval पर निर्भर करती हैं सीवी-योग्यvoid के लिए उचित परिणाम दे रही है। एक उदाहरण is_assignable है:

template <class T, class U> 
struct is_assignable; 

अभिव्यक्ति declval<T>() = declval<U>() अच्छी तरह से बनाई है जब एक unevaluated संकार्य के रूप में इलाज ...

आशय है कि "अच्छी तरह से गठित" है अच्छी तरह से को संदर्भित करता है असाइनमेंट अभिव्यक्ति की जानकारी-आधारित, और नहीं कि declval<T> स्वयं अच्छी तरह से गठित है। अर्थात। हम एक समय में सिर्फ एक चीज के बारे में चिंता करना चाहते हैं।

10

अंतर यह है कि add_rvalue_reference<> केवल && भाग जोड़ता है यदि T एक ऑब्जेक्ट या फ़ंक्शन प्रकार है। यदि T कोई ऑब्जेक्ट या फ़ंक्शन प्रकार नहीं है (उदा। void) आप && जोड़ना नहीं चाहते हैं।

this example on Ideone देखें।
This webpage of Boost's implementation बताते हैं:

समारोह टेम्पलेट declval() की भूमिका का उपयोग कर या इस समारोह का मूल्यांकन करने के बिना एक प्रकार T का एक परिवर्तन एक मूल्य में है।नाम पाठक के ध्यान को इस तथ्य पर निर्देशित करना है कि अभिव्यक्ति declval<T>() एक लवली है यदि केवल T एक लवली-संदर्भ है, अन्यथा एक रावल्यू। इस समारोह के डोमेन का विस्तार करने के लिए हम

template<class T> 
typename std::add_rvalue_reference<T>::type declval(); // not used 

जो सुनिश्चित करता है कि हम भी टेम्पलेट पैरामीटर के रूप में सीवी void उपयोग कर सकते हैं करने के लिए एक सा इसकी घोषणा बदलकर बेहतर कर सकते हैं।

संबंधित मुद्दे