2011-08-31 10 views
16

मैं merily नई अनुगामी वापसी प्रकार है, जहां मैं इस (सरलीकृत) कोड के साथ एक समस्या मारा के साथ प्रयोग किया गया थापीछे चल वापसी प्रकार, decltype और स्थिरांक सत्ता

#include <list> 

class MyContainer{ 
    std::list<int> ints; 

    auto begin() -> decltype(ints.begin()) 
    { 
    return ints.begin(); 
    } 

    auto begin() const -> decltype(ints.begin()) 
    { 
    return ints.begin(); 
    } 
}; 

कैसे व्यर्थ इस कोड है की इस तथ्य पर ध्यान न दें । महत्वपूर्ण हिस्सा (-std=c++0x ध्वज के साथ) संकलक जीसीसी 4.6.1 का उपयोग करते समय उत्पन्न त्रुटि है:

In member function 'std::list<int>::iterator MyContainer::begin() const': 
error: could not convert '((const MyContainer*)this)->MyContainer::ints.std::list<_Tp, _Alloc>::begin [with _Tp = int, _Alloc = std::allocator<int>, std::list<_Tp, _Alloc>::const_iterator = std::_List_const_iterator<int>]()' from 'std::list<int>::const_iterator {aka std::_List_const_iterator<int>}' to 'std::list<int>::iterator {aka std::_List_iterator<int>}' 

मामले में आप शामिल टेम्पलेट्स त्रुटि के प्रशंसक की नहीं कर रहे हैं, लघु कहानी है कि के शरीर में constMyContainer::begin का संस्करण, अभिव्यक्ति ints.begin()std::list<int>::const_iterator प्रकार का मान देता है (क्योंकि intsconst ऐसे संदर्भ में है)। हालांकि, decltype(ints.begin()) प्रकार std::list<int>::iterator, अर्थात decltypeपर ध्यान नहीं देताbegin विधि के const क्वालीफायर जब अभिव्यक्ति के प्रकार के निर्णय लेने से पैदा करता है। अनजाने में, परिणाम में एक संघर्ष परिणाम है।

यह मुझे जीसीसी कंपाइलर में एक बग होने लगता है। यह const क्वालीफायर का सम्मान करने के लिए केवल decltype के लिए समझ में आएगा और const_iterator प्रकार का उत्पादन करेगा। क्या कोई इस बात की पुष्टि या इनकार कर सकता है (शायद यहां तक ​​कि समझा सकता है)? शायद मैं decltype के यांत्रिकी में कुछ दिख रहा हूं, लेकिन यह एक सुंदर सीधा परिदृश्य की तरह दिखता है।

नोट: जहां तक ​​मैं कह सकता हूं, वही व्यवहार न केवल std::list<int> के लिए है, लेकिन किसी भी प्रकार के सदस्य कार्यों के साथ const -ness पर ओवरलोड किया गया है जो असंगत प्रकार लौटाता है।

+2

जीसीसी 4.7.0 के हालिया स्नैपशॉट के साथ त्रुटि के बिना संकलित करता है। तब तक, मुझे लगता है कि आप 'ints.cbegin()' – Cubbi

+0

से फंस गए हैं बेशक, इस तरह के एक मामूली मामले में यह गंभीर बाधा नहीं थी, लेकिन जीसीसी के लिए यह सभी गैर-मामूली मामलों (I यह भी सुनिश्चित करना चाहता था कि * मुझे * यह सही हो गया - मुझे उन सुविधाओं का उपयोग करने की कोई इच्छा नहीं है जिन्हें मैं समझ नहीं पा रहा हूं)। –

उत्तर

10

आप सही हैं, यह एक बग है। N3291, खंड 5.1.1, पैरा 3 के अनुसार:

एक घोषणा वाणी एक दसवीं कक्षा के एक सदस्य समारोह या सदस्य समारोह टेम्पलेट हैं, तो अभिव्यक्ति इस सीवी-quali फाई एर-सेक करने के लिए प्रकार के "सूचक एक prvalue है एक्स "वैकल्पिक सीवी-क्वालिफ़र-सीईसी और फ़ंक्शन-डेफिशन, सदस्य-घोषणाकर्ता, या घोषणाकर्ता के अंत के बीच। यह वैकल्पिक सीवी-क्वालिफ़ी-सीईसी से पहले नहीं दिखाई देगा और यह स्थिर सदस्य फ़ंक्शन की घोषणा के भीतर प्रकट नहीं होगा (हालांकि इसके प्रकार और मूल्य श्रेणी को स्थिर सदस्य फ़ंक्शन के भीतर डिफर्ड किया गया है क्योंकि वे एक गैर स्थैतिक सदस्य फ़ंक्शन के भीतर हैं) । [नोट: ऐसा इसलिए है क्योंकि पूर्ण घोषणाकर्ता ज्ञात होने तक घोषणा मिलान तब तक नहीं होता है। नोट नोट] अन्य संदर्भों में ऑब्जेक्ट अभिव्यक्ति के विपरीत, * सदस्य फ़ंक्शन बॉडी के बाहर कक्षा सदस्य पहुंच (5.2.5) के प्रयोजनों के लिए पूर्ण प्रकार की आवश्यकता नहीं है। [नोट: घोषणा से पहले घोषित केवल वर्ग के सदस्यों को दिखाई दे रहा है। -जेंड नोट]

लेकिन यह अंतिम कार्य ड्राफ्ट और एन 32 9 1 के बीच हालिया परिवर्तन था। तो जीसीसी 6 महीने पहले से कम था; यह एक चलती विनिर्देश के लिए कोड लिखने का खतरा है।

+0

यह मेरे विचारों का हिस्सा था, क्योंकि मुझे अंतिम मसौदे के बारे में कुछ चर्चा याद आई थी और पिछली वापसी के प्रकार में 'this' का उपयोग करके, लेकिन मुझे यकीन नहीं था कि वास्तव में किसी भी प्रस्ताव को स्वीकार किया गया था। अच्छी तरह से संदर्भित उत्तर के लिए धन्यवाद। शुक्र है (क्यूबी की टिप्पणी के मुताबिक), जीसीसी इस पर सबसे अच्छा प्रतीत होता है, क्योंकि संस्करण 4.7 पहले ही इस बदलाव को संबोधित करता है। –

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