7

दोनों जीसीसी 5.0 और बजना 3.6 निम्न उदाहरण में typename कीवर्ड की आवश्यकता होती है:क्या फेंकने या अभिव्यक्ति को कभी भी निर्भर किया जा सकता है?

template<typename T> 
struct B 
{ 
    typedef int Type; 
}; 

template<int n> 
struct A 
{ 
    typedef typename B<decltype(throw (int*)n)>::Type Throw; 
    typedef typename B<decltype(delete (int*)n)>::Type Delete; 
}; 

यह सी ++ 11 मानक में निम्नलिखित शब्दों द्वारा कवर किया जाता:

[छोड़कर]/2

एक फेंक-अभिव्यक्ति प्रकार शून्य है।

[expr.delete]/1

संकार्य प्रकार आपत्ति उठाने का एक सूचक है, या एक वर्ग प्रकार आपत्ति उठाने का एक सूचक के लिए एक एकल गैर स्पष्ट रूपांतरण समारोह होने प्रकार होगा। परिणाम शून्य शून्य है।

तो मुझे लगता है कि decltype दोनों मामलों में void उत्पन्न करता है।

[expr.const]/2

सशर्त अभिव्यक्ति एक कोर निरंतर अभिव्यक्ति है जब तक कि यह एक संभावित का मूल्यांकन उपसूचक

  • एक नई अभिव्यक्ति के रूप में निम्न में से एक शामिल है

  • एक थ्रो-अभिव्यक्ति

इससे पता चलता है कि throw या delete शामिल एक अभिव्यक्ति निरंतर अभिव्यक्ति नहीं हो सकती है।

[temp.dep.type]/8

एक प्रकार निर्भर है अगर यह

  • एक साधारण-टेम्पलेट-आईडी, जिसमें या तो टेम्पलेट का नाम टेम्पलेट पैरामीटर है या है टेम्पलेट के किसी भी तर्क एक आश्रित प्रकार या एक अभिव्यक्ति है कि प्रकार पर निर्भर या मूल्य पर निर्भर

  • decltype(expression), जहां अभिव्यक्ति टाइप-depende है द्वारा सूचित किया जाता है NT

तो B<decltype(..)> ही अगर अभिव्यक्ति टाइप पर निर्भर है निर्भर है।

[temp.dep।expr] निम्न रूपों में से/4

भाव टाइप पर निर्भर कभी नहीं किया है (क्योंकि अभिव्यक्ति के प्रकार निर्भर नहीं किया जा सकता):

delete cast-expression 
throw assignment-expression 

यह पता चलता है कि न तो अभिव्यक्ति प्रकार पर निर्भर हो सकता है ।

जीसीसी हैं और दोनों गलत बजना?

+0

मुझे नहीं लगता कि [temp.dep.constexpr]/p1 के बारे में आपकी तर्क सही है। एक 'reinterpret_cast' निरंतर अभिव्यक्ति में प्रकट नहीं हो सकता है, लेकिन [temp.dep.constexpr]/p3 स्पष्ट रूप से निर्दिष्ट करता है कि 'reinterpret_cast' से जुड़ी अभिव्यक्ति संभवतः मूल्य-निर्भर हो सकती है। –

+0

'decltype (..) 'एक अभिव्यक्ति नहीं है। तो आपको [temp.dep.type]/9.8 की भी आवश्यकता है। पैराग्राफ को केवल 'decltype (अभिव्यक्ति)' में अभिव्यक्ति की आवश्यकता होती है, जो * प्रकार-निर्भर * नहीं है, जो 'फेंक' और 'नया' के लिए अच्छी तरह से निर्दिष्ट है। – dyp

+0

@dyp हां! यह निर्णायक लगता है। – willj

उत्तर

7

चलो typename की आवश्यकता होने पर वापस जाएं। §14.6 [temp.res]/p3, सभी उद्धरण N4140 से कर रहे हैं:

जब एक योग्य-आईडी एक प्रकार है कि वर्तमान इन्स्टेन्शियशन के सदस्य नहीं है का उल्लेख करने का इरादा है (14.6.2.1) और उसके नेस्टेड-नाम-विनिर्देशक एक आश्रित प्रकार को संदर्भित करता है, यह कीवर्ड typename लगाया जाएगा, एक typename-विनिर्देशक गठन।

योग्य-आईडी इस मामले में B<decltype(throw (int*)n)>::Type है (और delete संस्करण है, जिसके लिए विश्लेषण बिल्कुल वैसा ही है)। तो आवश्यक है यदि नेस्टेड-नाम-विनिर्देशक, या B<decltype(throw (int*)n)>::, एक निर्भर प्रकार को संदर्भित करता है।

§14.6.2.1 [temp.dep.type]/p8 का कहना है कि छह असंबंधित छोड़े गए गोलियों से, कि

एक प्रकार निर्भर है अगर यह

[...]

है

(8.7) - एक सरल-टेम्पलेट आईडी जिसमें या तो टेम्पलेट का नाम एक टेम्पलेट पैरामीटर है या टेम्पलेट तर्क के किसी भी एक आश्रित प्रकार या एक अभिव्यक्ति है कि टाइप पर निर्भर या मूल्य पर निर्भर है, या है

(8,8) - decltype(अभिव्यक्ति), जहां अभिव्यक्ति टाइप पर निर्भर है (14.6.2.2) से दर्शाया जाता है।

B<decltype(throw (int*)n)> एक सरल-टेम्पलेट आईडी है। टेम्पलेट का नाम, B, टेम्पलेट पैरामीटर नहीं है। केवल टेम्पलेट तर्क, decltype(throw (int*)n), एक अभिव्यक्ति नहीं है, इसलिए B<decltype(throw (int*)n)> निर्भर है केवल यदि decltype(throw (int*)n) एक आश्रित प्रकार है। decltype(throw (int*)n), बारी में, गोली 8.8 प्रति, केवल निर्भर करता है, तो throw (int*)n प्रकार पर निर्भर है। लेकिन हम जानते हैं कि, प्रति §14.6.2.2 [temp.dep.expr]/p4:

निम्न रूपों में से

भाव टाइप पर निर्भर कभी नहीं किया है (क्योंकि अभिव्यक्ति के प्रकार पर निर्भर नहीं किया जा सकता):

[...]

::ऑप्टdeleteकच्चे अभिव्यक्ति

[...]

throwकाम अभिव्यक्ति ऑप्ट

[...]

इसलिए, throw (int*)n टाइप पर निर्भर नहीं है, और इसलिए decltype(throw (int*)n) एक आश्रित प्रकार नहीं है, और इसलिए B<decltype(throw (int*)n)> एक आश्रित प्रकार नहीं है, और इसलिए typenameB<decltype(throw (int*)n)>::Type लिए आवश्यक नहीं है, और इसलिए हाँ, यह एक संकलक बग है।

+0

आज मुझे अंत में एहसास हुआ कि मेरी गलती क्या है, और इसे आपके उत्तर में सही बताया गया है। 'decltype (...) 'एक अभिव्यक्ति नहीं है। मैंने कभी इस पर सवाल नहीं उठाया और '[temp.dep.constexpr]/1' से परेशान था। :) – Columbo

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

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