2016-11-17 10 views
10

कार्यक्रम निम्नलिखित पर विचार करें:कास्ट ऑपरेटर फ़ंक्शन g ++ में ठीक संकलित करता है लेकिन अन्य कंपाइलरों में नहीं। क्यूं कर?

struct S { 
    using T = float; 
    operator T() { return 9.9f; } 
}; 
int main() { 
    S m; 
    S::T t = m; 
    t = m.operator T(); // Is this correct ? 
} 

कार्यक्रम ग्राम में ठीक संकलित ++ (लाइव डेमो here देखें)

लेकिन यह बजना में ++ संकलन में विफल रहता है, MSVC++ & इंटेल C++ कम्पाइलर

बजना ++ निम्न त्रुटियों देता है (लाइव डेमो देखें here)

main.cpp:8:20: error: unknown type name 'T'; did you mean 'S::T'? 
    t = m.operator T(); // Is this correct ? 
       ^
        S::T 
main.cpp:2:11: note: 'S::T' declared here 
    using T = float; 

MSVC++ त्रुटियों (लाइव डेमो here देखें) निम्नलिखित देता

source_file.cpp(8): error C2833: 'operator T' is not a recognized operator or type 
source_file.cpp(8): error C2059: syntax error: 'newline' 

इंटेल सी ++ संकलक भी इस कोड (देखें लाइव डेमो here)

तो, सवाल जो संकलक यहीं है है को खारिज कर दिया? क्या G ++ यहां गलत है या अन्य 3 कंपाइलर्स गलत हैं? इस बारे में सी ++ मानक क्या कहता है?

+2

वाह, बहुत अच्छा सवाल! – Columbo

उत्तर

8

[basic.lookup.classref]/7:

आईडी अभिव्यक्ति एक रूपांतरण-समारोह-आईडी, अपने रूपांतरण प्रकार आईडी पहली वस्तु अभिव्यक्ति की कक्षा में ऊपर देखा जाता है तो और यदि नाम मिलता है, तो का उपयोग किया जाता है। अन्यथा यह पूरे पोस्टफिक्स-अभिव्यक्ति के संदर्भ में देखा गया है। इनमें से प्रत्येक लुकअप में, केवल वे नाम जो प्रकार या टेम्पलेट्स को दर्शाते हैं जिनके विशेषज्ञ प्रकार हैं। [उदाहरण:

struct A { }; 
namespace N { 
    struct A { 
    void g() { } 
    template <class T> operator T(); 
    }; 
} 

int main() { 
    N::A a; 
    a.operator A(); // calls N::A::operator N::A 
} 

- अंत उदाहरण]

यह बताता है कि उदाहरण हालांकि ऊपर के उदाहरण में, A पहले किसी प्रकार का नाम घोषित किया गया है, ठीक हो सकता है, दृश्य main पर।

यह core issue 156 में चर्चा की गई, सभी तरह से वापस दायर 1999 में:

कैसे के बारे में:

struct A { typedef int T; operator T(); }; 
struct B : A { operator T(); } b; 
void foo() { 
    b.A::operator T(); // 2) error T is not found in the context 
        // of the postfix-expression? 
} 

इस व्याख्या सही है? या यह त्रुटि होने का इरादा था, केवल T दोनों स्कॉप्स में पाया गया था और विभिन्न इकाइयों को संदर्भित किया गया था?

इरविन Unruh: इरादा यह था कि आप दोनों संदर्भों में देखते हैं। यदि आप इसे केवल एक बार पाते हैं, तो यह प्रतीक है। यदि आप इसे दोनों में पाते हैं, तो दोनों प्रतीकों को कुछ सम्मान में "वही" होना चाहिए। (यदि आपको यह नहीं मिला है, तो यह एक त्रुटि है)।

तो मैं कहेंगे बजना गलत है: के रूप में कुछ हद तक शब्दों में व्यक्त किया, इरादे, हम T लगता है कि, यहां तक ​​कि केवल कक्षा में अगर है।

+0

एक आश्चर्यजनक गचाचा! –

+0

आपको यह भी कहना चाहिए कि आईसीसी और एमएसवीसी ++ भी गलत हैं। केवल जी ++ सही है !!! – Destructor

+0

@ डिस्ट्रक्टर हां, लेकिन विशेष रूप से क्लैंग दिलचस्प है, क्योंकि यह आमतौर पर सही है। पिछले 10 या 20 भाषा-वकील प्रश्नों में क्लेंग और जीसीसी व्यवहार में भिन्न थे, क्लैंग सही था। – Columbo

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

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