2008-11-04 10 views
85

निम्नलिखित कोड का कहना है कि operator[] विधि में const के रूप में नक्शे गुजर क्वालिफायर को छोड़ देता है:सी ++ नक्शा पहुँच छोड देता है क्वालिफायर (स्थिरांक)

#include <iostream> 
#include <map> 
#include <string> 

using namespace std; 

class MapWrapper { 
public: 
    const int &get_value(const int &key) const { 
     return _map[key]; 
    } 

private: 
    map<int, int> _map; 
}; 

int main() { 
    MapWrapper mw; 
    cout << mw.get_value(42) << endl; 
    return 0; 
} 

यह संभव आवंटन है कि नक्शे का उपयोग पर होता है की वजह से है? नक्शा एक्सेस के साथ कोई फंक्शंस घोषित नहीं किया जा सकता है?

MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers

+0

बस एक nitpick, लेकिन मेगावाट MapWrapper के रूप में बस घोषित किया जा सकता मेगावाट; – luke

+0

अच्छा बिंदु - मैं कुछ भाषाओं में लिखता हूं इसलिए मैं उनके चारों ओर सिंटैक्स को सामान्यीकृत करता हूं ताकि वे मेरे सिर में फिट हो जाएं। :) – cdleary

+0

मैं इसकी सराहना कर सकता हूं। हालांकि सावधान रहें, इस तरह के मामलों में आपको एक अतिरिक्त ऑब्जेक्ट निर्माण और असाइनमेंट मिला है जो आवश्यक नहीं है। – luke

उत्तर

118

std::map's operator [] is not declared as const, and cannot be due to its behavior:

टी & ऑपरेटर [] (स्थिरांक कुंजी & कुंजी)

मूल्य उस कुंजी के लिए एक महत्वपूर्ण बराबर करने के लिए मैप किया गया है के लिए संदर्भ लौटाता, प्रविष्टि प्रदर्शन करता है, तो इस तरह के कुंजी पहले से नहीं है मौजूद।

नतीजतन, अपने कार्य const घोषित नहीं किया जा सकता, और नक्शे के operator[] का उपयोग करें।

std::map's find() फ़ंक्शन आपको मानचित्र को संशोधित किए बिना एक कुंजी देखने की अनुमति देता है।

find() एक iterator, या const_iterator एक std::pair दोनों कुंजी (.first) और मूल्य (.second) युक्त करने के लिए देता है।

सी ++ 11 में, आप std::map के लिए at() का भी उपयोग कर सकते हैं। यदि तत्व मौजूद नहीं है तो फ़ंक्शन operator [] के विपरीत std::out_of_range अपवाद फेंकता है।

+6

अतिरिक्त रूप से: VALUE = map.find (कुंजी) -> दूसरा; मुझे यह सीखना था कि 'ढूंढें()' एक इटेटरेटर देता है, जो कि प्रकार की जोड़ी है। – FlipMcF

+4

मैं अब उस सी 11 में जोड़ दूंगा, आप इसका उपयोग कर सकते हैं: std :: map :: at (key) और iterator से बचें। –

+2

दिलचस्प। मुझे लगता है कि सी ++ lvalue 'ऑपरेटर []' (उदा। 'Foo [bar] = baz') और rvalue 'ऑपरेटर []' (उदा। 'X = foo [bar]') के बीच अंतर करेगा - बाद वाला निश्चित रूप से स्थिर हो सकता है। – Claudiu

10

आप एक नक्शा है कि विधि const नहीं है के रूप में यह आप नक्शे को संशोधित करने की अनुमति देता है के रूप में स्थिरांक है कि पर ऑपरेटर [] का उपयोग नहीं कर सकते हैं (आप _map को असाइन कर सकते [कुंजी])। इसके बजाय खोज विधि का उपयोग करने का प्रयास करें।

+1

स्पष्टीकरण के माध्यम से: मानचित्र का ऑपरेटर क्या करना चाहिए [] यदि कुंजी मौजूद नहीं है तो क्या करें? यदि नक्शा गैर-स्थिर है, तो कुंजी डिफ़ॉल्ट-निर्मित मान के साथ जोड़ा जाता है। यदि मानचित्र का आधार है, ऑपरेटर [] द्वारा क्या वापस किया जा सकता है? उस कुंजी पर कोई मूल्य नहीं है। – Arkadiy

7

जीसीसी शीर्षकों (4.1 और 4.2 मेरी मशीन पर 4.2) के कुछ नए संस्करणों में गैर मानक सदस्य फ़ंक्शन मैप :: पर() हैं जिन्हें कॉन्स घोषित किया गया है और यदि कुंजी मानचित्र में नहीं है तो std :: out_of_range फेंक दें।

const mapped_type& at(const key_type& __k) const 

समारोह की टिप्पणी में एक संदर्भ से, ऐसा लगता है कि यह मानक पुस्तकालय में एक नए सदस्य के समारोह के रूप में सुझाव दिया गया है।

+0

मुझे लगता है कि यह थोड़ा सा क्विर्क है। एट-फ़ंक्शन आने वाले मानक का हिस्सा है, लेकिन मुझे वर्तमान में कोई() नहीं मिला है। –

+0

ने एक बग रिपोर्ट दायर की: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46544 –

+0

'at' सी ++ 11 का हिस्सा है। –

0

सबसे पहले, आप के साथ शुरुआत प्रतीकों का उपयोग नहीं किया जाना चाहिए, क्योंकि वे _ भाषा कार्यान्वयन/संकलक लेखक के लिए आरक्षित हैं। _map किसी के कंपाइलर पर सिंटैक्स त्रुटि होने के लिए बहुत आसान होगा, और आपके पास कोई दोष नहीं होगा लेकिन स्वयं।

आप एक अंडरस्कोर का उपयोग करना चाहते हैं, तो यह अंत नहीं, शुरुआत में डाल दिया। आपने शायद यह गलती की है क्योंकि आपने कुछ माइक्रोसॉफ्ट कोड इसे देखा है। याद रखें, वे अपना स्वयं का कंपाइलर लिखते हैं, इसलिए वे इससे दूर हो सकते हैं। फिर भी, यह एक बुरा विचार है।

ऑपरेटर [] न केवल रिटर्न एक संदर्भ, यह वास्तव में नक्शे में प्रविष्टि बना देता है। तो तुम सिर्फ एक मानचित्रण हो रही नहीं कर रहे हैं, अगर वहाँ कोई भी है, तो आप एक बना रहे हैं। यही वह नहीं है जिसका आप इरादा रखते थे।

+4

'_' के बारे में आपका बिंदु सिर्फ गलत है। दो अंडरस्कोर ('__example') से शुरू होने वाले पहचानकर्ता या एक अंडरस्कोर और पूंजी अक्षर (' _Example') शुरू करने वाले पहचानकर्ता आरक्षित हैं। '_example' आरक्षित नहीं है। – Ethan

9

operator[] के बाद से एक स्थिरांक योग्य अधिभार इसे सुरक्षित रूप से एक स्थिरांक योग्य समारोह में नहीं किया जा सकता है नहीं है,।ऐसा शायद इसलिए है क्योंकि वर्तमान अधिभार दोनों महत्वपूर्ण मूल्यों को वापस करने और सेट करने के लक्ष्य के साथ बनाया गया था।

इसके बजाय, आप उपयोग कर सकते हैं:

VALUE = map.find(KEY)->second; 

या, सी ++ 11 में, आप at() ऑपरेटर का उपयोग कर सकते हैं:

VALUE = map.at(KEY);