STL नक्शे के लिए [] ऑपरेटर कांस्टेबल क्यों नहीं है?


89

उदाहरण के लिए, प्रश्न के लिए:

void MyClass::MyFunction( int x ) const
{
  std::cout << m_map[x] << std::endl
}

यह संकलित नहीं करेगा, क्योंकि [] ऑपरेटर गैर-कास्ट है।

यह दुर्भाग्यपूर्ण है, क्योंकि [] वाक्यविन्यास बहुत साफ दिखता है। इसके बजाय, मुझे ऐसा कुछ करना होगा:

void MyClass::MyFunction( int x ) const
{
  MyMap iter = m_map.find(x);
  std::cout << iter->second << std::endl
}

इसने मुझे हमेशा अचंभित किया है। [] ऑपरेटर गैर-कॉन्स्टेबल क्यों है?


5
operator[]दिए गए तत्व के मौजूद न होने की स्थिति में उपज क्या होनी चाहिए ?
फ्राइरिच राबे

4
@ फ़्रीचैक रेबे: सदस्य समारोह में एक ही चीज़: थ्रेड :: out_of_range
जीन-साइमन

जवाबों:


90

के लिए std::mapऔर std::unordered_map, operator[]कंटेनर में सूचकांक मान सम्मिलित करता है, तो यह पहले से मौजूद नहीं था होगा। यह थोड़ा अचूक है, लेकिन यह जिस तरह से है।

चूँकि इसे विफल करने और डिफ़ॉल्ट मान सम्मिलित करने की अनुमति दी जानी चाहिए, ऑपरेटर constको कंटेनर के उदाहरण पर उपयोग नहीं किया जा सकता है ।

http://en.cppreference.com/w/cpp/container/map/operator_at


3
std::setनहीं है operator[]
अवकर

2
यह सही उत्तर है, लेकिन एक कास्ट संस्करण "एट" सदस्य के समान काम कर सकता है। वह एक std फेंक रहा है :: out_of_range ...
Jean-Simon Brochu

जब कोई मान पढ़ने के लिए उपयोग किया जाता है तो प्रदान करने के लिए कोई डिफ़ॉल्ट मान नहीं होता है। std::vectorएक रीड ऑपरेटर है []जो है constmapवैसा ही करना चाहिए।
wcochran

51

अब C ++ 11 के साथ () का उपयोग करके आप एक क्लीनर संस्करण रख सकते हैं

void MyClass::MyFunction( int x ) const
{
  std::cout << m_map.at(x) << std::endl;
}

4
अगर mapकॉन्स्टेबल और नॉन-कॉन्स्टैन्ड है at()- तो उसी के लिए भी क्यों नहीं operator[]? कास्ट संस्करण के साथ कुछ भी नहीं डाल रहा है, बल्कि फेंक रहा है? (या एक वैकल्पिक लौटने पर, जब std :: वैकल्पिक इसे मानक में बनाता है)
einpoklum

@einpoklum कांस्टीट्यूशन की बात ज्यादातर स्थिर संकलन-समय की जाँच है। मैं बल्कि कंपाइलर शिकायत को एक अपवाद के बजाय फेंक देता हूं क्योंकि मैंने कास्ट ऑब्जेक्ट्स का सही उपयोग नहीं किया है।
मिल्ली स्मिथ

@einpoklum बहुत देर से, लेकिन अन्य पाठकों के लिए: इस तरह के अलग-अलग काम करने वाले दो अधिभार भयानक होंगे। एकमात्र कारण atदो स्वादों में आता है क्योंकि यह एक करता है return *this;, और ओवरलोड के बीच एकमात्र अंतर constलौटे संदर्भ का है। दोनों के वास्तविक प्रभाव atएक ही हैं (अर्थात, कोई प्रभाव नहीं)।
HTNW

28

नए पाठकों के लिए ध्यान दें।
मूल प्रश्न STL कंटेनरों के बारे में था (विशेषकर std :: map के बारे में नहीं)

यह ध्यान दिया जाना चाहिए कि अधिकांश कंटेनरों पर ऑपरेटर [] का एक कास्ट संस्करण है।
यह सिर्फ इतना है कि एसटीडी :: नक्शा और एसटीडी :: सेट में एक कास्ट संस्करण नहीं है और यह अंतर्निहित संरचना का एक परिणाम है जो उन्हें लागू करता है।

एसटीडी :: वेक्टर से

reference       operator[](size_type n) 
const_reference operator[](size_type n) const 

इसके अलावा अपने दूसरे उदाहरण के लिए आपको तत्व को खोजने में विफलता के लिए जांच करनी चाहिए।

void MyClass::MyFunction( int x ) const
{
    MyMap iter = m_map.find(x);
    if (iter != m_map.end())
    {
        std::cout << iter->second << std::endl
    }
}

1
std::setबिल्कुल नहीं है operator[]
हर कोई

2

चूंकि ऑपरेटर [] कंटेनर में एक नया तत्व सम्मिलित कर सकता है, यह संभवतः एक कास्ट सदस्य फ़ंक्शन नहीं हो सकता है। ध्यान दें कि ऑपरेटर की परिभाषा अत्यंत सरल है: m [k] के बराबर है (* (m.insert (value_type (k, data_type ()))) प्रथम)। दूसरा। सख्ती से बोलना, यह सदस्य कार्य अनावश्यक है: यह केवल सुविधा के लिए मौजूद है


0

एक इंडेक्स ऑपरेटर केवल रीड-ओनली कंटेनर (जो वास्तव में एसटीएल में मौजूद नहीं है) के लिए कास्ट होना चाहिए।

सूचकांक ऑपरेटरों का उपयोग केवल मूल्यों को देखने के लिए नहीं किया जाता है।


6
सवाल यह है कि यह दो अतिभारित संस्करण क्यों नहीं है - एक const, एक और गैर- constजैसे कि std::vectorकरता है।
पावेल मिनेव

-2

यदि आप अपना std :: मैप सदस्य चर घोषित करते हैं तो यह परिवर्तनशील है

mutable std::map<...> m_map;

आप अपने कॉन्स्टेबल सदस्य कार्यों के भीतर std :: मैप के नॉन-कास्ट सदस्य कार्यों का उपयोग कर सकते हैं।


15
हालांकि यह एक भयानक विचार है।
GMANNICKG

7
यदि आप ऐसा करते हैं तो आपकी कक्षा के लिए एपीआई निहित है। फ़ंक्शन का दावा है कि यह const - अर्थ है कि यह किसी भी सदस्य चर को संशोधित नहीं करेगा - लेकिन वास्तव में यह m_map डेटा सदस्य को संशोधित कर सकता है।
रिबबल

2
mutableसदस्यों std::mutex, कैश और डिबग हेल्पर्स जैसे सदस्यों के लिए उपयोग किया जा सकता है । यदि मानचित्र को बहुत महंगे const"गेट्टर" फ़ंक्शन को गति देने के लिए कैश के रूप में उपयोग किया जाना है , तो mutableस्वीकार्य है। आपको सावधान रहने की जरूरत है, लेकिन यह अपने आप में एक भयानक विचार नहीं है।
मार्क लकाटा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.