2010-01-10 13 views
7

मैंने हाल ही में एक विषम मुद्दे में भाग लिया जहां मुझे const_iterator की अपेक्षा की गई iterator की बजाय एक मल्टीसेट के माध्यम से पुनरावृत्ति हो रही थी। यह पता चला ++ मुझे एक त्रुटि दे दी MSVC लेकिन जी के लिए एक गैर मुद्दा:सी ++ मानक: मल्टीसेट में अप्रत्याशित const_iterator

error: invalid initialization of reference of type 'myPtr&' from expression of type 'const boost::shared_ptr'

प्रासंगिक कोड:

typedef std::multiset<myPtr> myList; 
myList _mystuff; 
void tick(float dt) 
{ 
    for (myList::iterator i = _mystuff.begin(); i != _mystuff.end(); ++i) 
    { 
     myPtr &mine = *i; // g++ problem here, not for MSVC 
     // const myPtr &mine = *i; works fine for g++ 
     mine->tick(dt); 
    } 
} 

अनुसंधान के काफी एक सा पता चला है कि पिछली चर्चा के बहुत सारे के साथ एक समस्या है । मैं इन प्रासंगिक बिट पाया:

मेरी पृष्ठभूमि ज्ञान और इस मुद्दे पर काबू सीमित है और इस तरह मैं था यह जानना कि मानक इसे परिभाषित नहीं करता है या नहीं व्यवहार अच्छी तरह से पर्याप्त है जिसमें जी ++ और एमएसवीसी व्यवहार को अपनी पसंद के अनुसार लागू करते हैं या फिर जी ++ या एमएसवीसी एक अच्छी तरह से परिभाषित मानक से विचलित हो।

अग्रिम धन्यवाद।

+0

परिवर्तन 'स्थिरांक myPtr और mine' को 'मेरी' की डीईसीएल। बेशक, 'टिक' को 'शून्य टिक (फ्लोट) कॉन्स घोषित किया जाना चाहिए;' और टिक द्वारा संशोधित किसी भी डेटा सदस्य को 'उत्परिवर्तनीय' होना आवश्यक होगा। – KitsuneYMG

उत्तर

15

सेट और मल्टीसेट के लिए इटरेटर मानक इटरेटर/कॉन्स इटरेटर जोड़ी से बदलकर केवल इस्टेटेटर होने के लिए बदल दिए गए थे। इस परिवर्तन का कारण यह था कि उन्हें कंटेनरों का आदेश दिया जाता है, और एक पुनरावर्तक के अंदर तत्व को बदलना वास्तव में इस आदेश की बाधा को अमान्य कर सकता है।

जीसीसी का संस्करण जिसके खिलाफ आप परीक्षण कर रहे हैं, इस बदलाव को बना दिया है, जिसका उपयोग आप कर रहे हैं वीसी का संस्करण नहीं है। वीसी 10 (और वीसी 9 एसपी 1, मेरा मानना ​​है) हमेशा सेट और मल्टीसेट से const_iterators लौटते हैं।

23.2.4/C++ 1x (इस समय n3000.pdf) के नवीनतम मसौदे के 6 कहते हैं

For associative containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators.

std :: सेट और std :: multi_set साहचर्य कंटेनरों जहां मान रहे हैं प्रकार कुंजी प्रकार के समान है।

+0

बहुत बढ़िया! मैंने अभी वीसी 10 बी 2 का परीक्षण किया और वास्तव में मुझे एक ही त्रुटि मिली।अब अगर मैं केवल समझ गया कि मानक के किस हिस्से ने इसे वास्तव में परिभाषित किया है। – Svenstaro

+0

सी ++ 1x के नवीनतम मसौदे के 23.2.4/6 कहते हैं, "सहयोगी कंटेनरों के लिए जहां मूल्य प्रकार कुंजी प्रकार के समान होता है, दोनों इटरेटर और कॉन्स्ट_इटरेटर स्थिर इटरेटर होते हैं।" std :: set और std :: multi_set सहयोगी कंटेनर हैं जहां मान प्रकार कुंजी प्रकार के समान होता है। –

1

std :: set :: iterator के लिए कंपाइलर को मूर्ख कैसे बनाएं?

मैं struct है

struct _item { 
    int a; 
    int b; 
    bool operator <(const _item& x) const {return a<x.a;} 
}; 

मैं बदल केवल सदस्य ख चाहते हैं (ख सेट में छँटाई के लिए अप्रासंगिक है, केवल सदस्य एक तुलना की जाती है)।

std::set<_item> data; 
std::set<_item>::iterator iter=data.begin(); 
iter->b=0; // error !!! 

अवदा केदवरा!

struct _item { 
    int a; 
    int b; 
    _item* self; 
    _item() {self=this;} 
    bool operator <(const _item& x) const {return a<x.a;} 
}; 
iter->self->b=0; // Success !! Tested on VC10 

बेशक अधिक सी + + सही ढंग से

struct _item { 
    int a; 
    int b; 
private: 
    _item* self; 
public: 
    _item() {self=this;} 
    bool operator <(const _item& x) const {return a<x.a;} 
    int& bReference() const {return self->b;} 
}; 
std::set<_item> items; 
std::set<_item>::iterator iter=items.begin(); 
iter->bReference()=0; // Success !! Tested on VC1 
+1

वह मानक मानक चाहता है और कामकाज नहीं – owagh

+0

या आप 'const_cast' का उपयोग कर सकते हैं। वैसे, यदि आपका तत्व कॉपी या असाइन किया गया है तो आपका समाधान विफल हो जाता है। – immibis

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