2010-03-26 17 views
11

से शुरू होने पर सेट पर इटरेटर को डिफ्रेंस करते समय कॉन्स्ट रेफरेंस, विजुअल स्टूडियो 2010 से शुरू होने पर, एक सेट पर पुनरावृत्ति एक पुनरावर्तक को वापस लौटाता है जो डेटा को गैर-कॉन्स के बजाय 'कॉन्स्ट डेटा' के रूप में संदर्भित करता है।विजुअल स्टूडियो 2010

निम्नलिखित कोड कुछ ऐसा उदाहरण है जो विजुअल स्टूडियो 2005 पर संकलित करता है, लेकिन 2010 पर नहीं (यह एक कृत्रिम उदाहरण है, लेकिन स्पष्ट रूप से हमारे द्वारा अपने कोड पर मिली समस्या को स्पष्ट करता है)।

इस उदाहरण में, मेरे पास एक कक्षा है जो तापमान के साथ एक स्थिति को स्टोर करती है। मैं तुलना ऑपरेटर परिभाषित करता हूं (उन सभी को नहीं, समस्या को स्पष्ट करने के लिए पर्याप्त है) जो केवल स्थिति का उपयोग करते हैं, तापमान नहीं। मुद्दा यह है कि मेरे लिए दो उदाहरण समान हैं यदि स्थिति समान है; मुझे तापमान की परवाह नहीं है।

#include <set> 

class DataPoint 
    { 
    public: 
     DataPoint (int x, int y) : m_x(x), m_y(y), m_temperature(0) {} 
     void setTemperature(double t) {m_temperature = t;} 
     bool operator<(const DataPoint& rhs) const 
     { 
     if (m_x==rhs.m_x) return m_y<rhs.m_y; 
     else    return m_x<rhs.m_x; 
     } 
     bool operator==(const DataPoint& rhs) const 
     { 
     if (m_x!=rhs.m_x) return false; 
     if (m_y!=rhs.m_y) return false; 
     return true; 
     } 
    private: 
     int m_x; 
     int m_y; 
     double m_temperature; 
    }; 

typedef std::set<DataPoint> DataPointCollection; 

void main(void) 
{ 
DataPointCollection points; 

points.insert (DataPoint(1,1)); 
points.insert (DataPoint(1,1)); 
points.insert (DataPoint(1,2)); 
points.insert (DataPoint(1,3)); 
points.insert (DataPoint(1,1)); 

for (DataPointCollection::iterator it=points.begin();it!=points.end();++it) 
    { 
    DataPoint &point = *it; 
    point.setTemperature(10); 
    } 
} 

मुख्य दिनचर्या में मेरे पास एक सेट है जिसमें मैं कुछ बिंदु जोड़ता हूं। तुलना ऑपरेटर की शुद्धता की जांच करने के लिए, मैं एक ही स्थिति के साथ कई बार डेटा अंक जोड़ता हूं। सेट की सामग्री लिखते समय, मैं स्पष्ट रूप से देख सकता हूं कि सेट में केवल 3 अंक हैं।

सेट पर लूप लूप सेट करता है, और तापमान सेट करता है। तर्कसंगत रूप से इसकी अनुमति है, क्योंकि तापमान ऑपरेटरों में तापमान का उपयोग नहीं किया जाता है।

इस कोड को विजुअल स्टूडियो 2005 में सही ढंग से संकलित है, लेकिन निम्न पंक्ति पर दृश्य स्टूडियो 2010 में संकलन त्रुटियों देता है (के लिए लूप में):

DataPoint &point = *it; 

दिया त्रुटि है कि यह असाइन नहीं कर सकते एक [गैर-कॉन्स] "डेटापॉइंट &" पर "कॉन्स्ट डेटापॉइंट"।

ऐसा लगता है कि आपके पास VS2010 में इस कोड को लिखने का कोई सभ्य (= गैर-गंदा) तरीका नहीं है यदि आपके पास एक तुलना ऑपरेटर है जो केवल डेटा सदस्यों के हिस्सों की तुलना करता है।

संभव समाधान हैं:

  • लाइन जहां यह एक त्रुटि
  • मेकिंग तापमान परिवर्तनशील देता है के लिए एक स्थिरांक-कास्ट जोड़ना और setTemperature एक स्थिरांक विधि

बनाने लेकिन दोनों समाधान मेरे लिए बल्कि 'गंदे' लगते हैं।

ऐसा लगता है कि सी ++ मानक समिति ने इस स्थिति को अनदेखा किया। या नहीं?

इस समस्या को हल करने के लिए साफ समाधान क्या हैं? क्या आप में से कुछ ने भी यही समस्या का सामना किया और आपने इसे कैसे हल किया?

पैट्रिक

+1

http://connect.microsoft.com/VisualStudio/feedback/details/532300/std-set-t-iterator-and-std-set-t-const-iterator-are-the- समान प्रकार के ब्रेक-कोड – mlvljr

+1

अच्छा लिंक। ऐसा लगता है कि मैं अकेला नहीं हूं जो इसे मिला। – Patrick

+0

यूप, मैंने अभी कुछ (अब स्पष्ट रूप से) गलत stl :: सेट कोड लिखा है और यह एक घंटे के डिबगिंग के बाद-और-यह गुगल रहा है, यहां और वहां दोनों आ रहा है :) – mlvljr

उत्तर

13

इटरेटर आप एक स्थिरांक संदर्भ देना चाहिए (और कहा कि मानक का कहना है कि यह करना चाहिए), क्योंकि बात के लिए भेजा बदलते सेट की अंतर्निहित डेटा संरचना की वैधता को नष्ट कर देगी करने के लिए - सेट नहीं करता है ' टी "पता" कि आप जिस क्षेत्र को बदल रहे हैं वह वास्तव में कुंजी का हिस्सा नहीं है। विकल्पों को हटाने और पुनः जोड़ने, या इसके बजाय std :: मानचित्र का उपयोग करने के लिए परिवर्तन करना है।

+0

यदि इस समस्या को पूर्व- साथ काम करने वाला। व्यक्तिगत रूप से मैं वास्तव में std :: मानचित्र का उपयोग करता हूं, लेकिन मेरे लिए यह कस्टम तुलना ऑपरेटर की तरह दिखता है और सेट VS2010 में अच्छी तरह से फिट नहीं होता है। – Patrick

+4

कस्टम तुलना और सेट बस ठीक के साथ जाते हैं, लेकिन परिवर्तनीय डेटा-प्रकार और सेट नहीं होते हैं। –

0

आप को दूर करने और फिर से जोड़ने नील पता चलता है के रूप में आप setTemperatureconst और m_temperaturemutable कर सकता है के लिए नहीं करना चाहते हैं।

+0

बस मैंने अपने प्रश्न में क्या कहा। हालांकि यह काम करता है, मुझे अभी भी यह एक सभ्य समाधान नहीं मिला है। – Patrick

0

सेट को कॉन्स्ट इटरेटर वापस करना माना जाता है क्योंकि यह नहीं जानता कि कोई सदस्य फ़ंक्शन ऑर्डरिंग बदल सकता है या नहीं।

ऐसा लगता है कि आप वास्तव में एक मानचित्र चाहते हैं, जहां आप एक परिवर्तनीय तापमान के लिए अपनी अपरिवर्तनीय (x, y) कुंजी को मैप करते हैं।

1

हाल ही में 2010 में हमारा रूपांतरण शुरू हुआ और यह सबसे बड़ी बाधा थी जिसे हम सामना कर रहे थे। सौभाग्य से उन्होंने कुछ दीर्घकालिक समस्याओं को प्रकट किया जहां हम सेट के आदेश को तैयार करने के हिस्से को बदल रहे थे।

अन्य मामलों में, हमारा समाधान म्यूटेबल और घोषणा विधियों का उपयोग करना था। रेफरेंस (या तो पॉइंटर या रेफरेंस) द्वारा किसी फ़ंक्शन में ड्रेन्सेन्स्ड इटरेटर को पास करते समय, जब हम बदला नहीं जा रहा था तो हमने तर्क को रोक दिया।

डेनिस

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