C ++ मैप एक्सेस डिस्क्लेमर क्वालीफायर (const)


113

निम्नलिखित कोड का कहना है कि के रूप में नक्शे गुजर constमें operator[]विधि छोड देता है क्वालिफायर:

#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


बस एक नाइटपिक, लेकिन mw को केवल MapWrapper mw के रूप में घोषित किया जा सकता है;
ल्यूक

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

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

एक और अच्छा बिंदु - डिफ़ॉल्ट असाइनमेंट ऑपरेटर पर भरोसा करना सार्वजनिक उदाहरणों के लिए एक अच्छा अभ्यास नहीं है। ;)
cdleary

जवाबों:


152

std::mapके operator []रूप में घोषित नहीं किया गया है const, और इसके व्यवहार के कारण नहीं हो सकता है:

टी एंड ऑपरेटर [] (कांस्ट की एंड की)

मान के लिए एक संदर्भ देता है जो कुंजी के बराबर एक कुंजी के लिए मैप किया जाता है, सम्मिलन का प्रदर्शन अगर ऐसी कुंजी पहले से मौजूद नहीं है।

परिणामस्वरूप, आपका फ़ंक्शन घोषित नहीं किया जा सकता है const, और मैप का उपयोग कर सकते हैं operator[]

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

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

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


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

5
मुझे लगता है कि अब C11 में आप उपयोग कर सकते हैं: std :: map :: at (की) और itter से बचें।
जुआन बेसा

3
दिलचस्प। मुझे लगता है कि सी ++ लैवल्यू operator[](जैसे foo[bar] = baz) और रिवेल्यू operator[](जैसे x = foo[bar]) के बीच अंतर करेगा - उत्तरार्द्ध निश्चित रूप से कास्ट हो सकता है।
क्लाउडीयू

15

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

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

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

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

VALUE = map.at(KEY);

map.find(KEY)->second; नक्शा मान तार होने पर असुरक्षित है। यह कुंजी नहीं मिलने पर कचरा प्रिंट करता है।
syam

1
यह ठीक से समझाया गया उत्तर है जो इस बिंदु पर जाता है। कल मैंने 2 घंटे बिताए यह पता लगाने की कोशिश कर रहा था कि एक समान मामले के साथ क्या हो रहा है। क्या हम इस बात से सहमत हो सकते हैं कि त्रुटि संदेश, सबसे अच्छा, भ्रामक है? मैं और अधिक स्पष्ट हो सकता हूं यदि इसमें 'यह' शब्द नहीं है और अधिक सामान्य योग्यता के बजाय कॉन्स्ट-नेस का संदर्भ दिया है ।
कार्निसर

11

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


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

यह ठीक से समझाया गया उत्तर है जो इस बिंदु पर जाता है। कल मैंने 2 घंटे बिताए यह पता लगाने की कोशिश कर रहा था कि एक समान मामले के साथ क्या हो रहा है। क्या हम इस बात से सहमत हो सकते हैं कि त्रुटि संदेश, सबसे अच्छा, भ्रामक है? मैं और अधिक स्पष्ट हो सकता हूं यदि इसमें 'यह' शब्द नहीं है और अधिक सामान्य योग्यता के बजाय कॉन्स्ट-नेस का संदर्भ दिया है ।
कार्निसर

7

जीसीसी हेडर के कुछ नए संस्करणों (मेरी मशीन पर 4.1 और 4.2) में गैर-मानक सदस्य फ़ंक्शंस मैप हैं :: पर () जो कि कॉन्स्टेबल और थ्रो std :: out_of_range हैं यदि कुंजी मैप में नहीं है।

const mapped_type& at(const key_type& __k) const

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


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

'at' C ++ 11 का हिस्सा है।
.तिने

0

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

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

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


5
आपकी बात _सिर्फ गलत है। दो अंडरस्कोर ( __example) या एक अंडरस्कोर और एक कैपिटल लेटर ( _Example) से शुरू होने वाले आइडेंटिफ़ायर की पहचान होती है । _exampleआरक्षित नहीं है।
एथन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.