2011-09-09 8 views
8

मैं यह पता लगाने की कोशिश कर रहा था कि एक कॉन्स विधि में किसी मानचित्र से मूल्य कैसे वापस किया जाए और मैं gcc 4.6 में मानचित्र के लिए() विधि पर ठोकर खाई।सी ++ 11 में मानचित्र मानक के लिए() कॉन्स्ट एक्सेसर है?

जब मैं इस ऊपर देखा मुझे एहसास हुआ कि यह गैर मानक था:

C++ map access discards qualifiers (const)

लेकिन यह यकीन है कि एक पूरी बहुत कम खोज() दृष्टिकोण से वर्बोज़ है। मैं सोच रहा था कि क्या सी ++ 11 ने इसे सुधार लिया है - नए मानक के मानचित्र भाग के लिए() पर है?

उत्तर

17

हां।

T&  at(const key_type& x); 
const T& at(const key_type& x) const; 

रिटर्न: mapped_type *this में x करने के लिए इसी का संदर्भ std::map सी ++ 11 निम्नलिखित विनिर्देश (23.4.4.3/9) के साथ में एक at सदस्य समारोह है।

फेंकता है: यदि कोई ऐसा तत्व मौजूद नहीं है तो out_of_range प्रकार का एक अपवाद ऑब्जेक्ट।

जटिलता: लॉगरिदमिक।

नोट हालांकि यह सदस्य फ़ंक्शन विशेष रूप से std::map पर जोड़ा गया है। यह अधिक सामान्य सहयोगी कंटेनर आवश्यकता से आवश्यक नहीं है। यदि आप जेनेरिक कोड लिख रहे हैं जिसके लिए कुछ सहयोगी कंटेनर प्रकार की आवश्यकता है, तो आप इस नए at का उपयोग नहीं कर सकते हैं। इसके बजाय, आप find उपयोग करने के लिए है, जो साहचर्य कंटेनर अवधारणा का हिस्सा है जारी रखना चाहिए, या अपने स्वयं गैर सदस्य सहायक लिखें:

template <typename AssociativeContainer> 
typename AssociativeContainer::mapped_type& 
get_mapped_value(AssociativeContainer&       container, 
       typename AssociativeContainer::key_type const& key) 
{ 
    typename AssociativeContainer::iterator it(container.find(key)); 
    return it != container.end() ? it->second : throw std::out_of_range("key"); 
} 

template <typename AssociativeContainer> 
typename AssociativeContainer::mapped_type const& 
get_mapped_value(AssociativeContainer const&     container, 
       typename AssociativeContainer::key_type const& key) 
{ 
    typename AssociativeContainer::const_iterator it(container.find(key)); 
    return it != container.end() ? it->second : throw std::out_of_range("key"); 
} 

या, यदि आप एक कार्यान्वयन कि rvalue संदर्भ और decltype का समर्थन करता है है, आप दो भार के की जरूरत नहीं है:

template <typename AssociativeContainer, typename Key> 
auto get_mapped_value(AssociativeContainer&& container, Key const& key) 
    -> decltype(std::declval<AssociativeContainer>().begin()->second)& 
{ 
    auto const it(container.find(key)); 
    return it != container.end() ? it->second : throw std::out_of_range("key"); 
} 

(या कि के करीब कुछ है, एक मजेदार बात के बारे में सी ++ 11 कि कोई भी दो compilers एक ही कीड़े है और सभी मान्य प्रतीत नहीं होती- का थोड़ा अलग सबसेट स्वीकार करने के लिए लग रहे है -और अमान्य - सी ++ 11 कोड।)

+0

मैं कहूंगा कि सभी कंपाइलर सी ++ 11 पर बंद हो रहे हैं, लेकिन यह मेरा आशावादी आत्म हो सकता है :) –

+1

[nitpick]। 'at' विधि न केवल std :: map में जोड़ा गया था, लेकिन std :: unordered_map के साथ भी जोड़ा गया था। ये केवल दो मानक कंटेनर हैं जो वास्तव में इस विधि के लिए समझ में आता है। इसके अलावा आपका कोड न केवल एसोसिएटवेन्टर्स के लिए काम करेगा, बल्कि अनॉर्डर्डएसिओटेटवेकंटर्स के लिए भी सेट और अनॉर्डर्ड_सेट को छोड़कर, और फिर, यह शायद ही कभी मल्टीमैप और अनॉर्डर्ड_मल्टीमैप के लिए समझ में आता है। –

+0

@ कॉन्स्टेंटिन: हां, शायद 'अनन्य एसिओसिटिव कंटेंसर' टेम्पलेट पैरामीटर के लिए एक बेहतर नाम होगा ('UniqueAssociativeContainerOrUniqueUnorderedAssociativeContainer' थोड़ा बहुत अनावश्यक है: -ओ)। मुद्दा यह है कि सी ++ मानक लाइब्रेरी कंटेनर के अलावा कंटेनर हैं जो कंटेनर अवधारणाओं की आवश्यकताओं को पूरा करते हैं और जेनरिक कोड में सी ++ मानक लाइब्रेरी कंटेनर के साथ अंतर-परिवर्तनीय होना चाहिए। कोड जो नए 'एटी' पर निर्भर करता है, उन अन्य कंटेनरों का उपयोग नहीं कर सकता है। –

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