2012-06-07 14 views
12

मैं सी ++ 11 वाक्यविन्यास का उपयोग कर एक एसटीएल मानचित्र शुरू करने की कोशिश कर रहा हूं लेकिन ऐसा लगता है कि यह काम नहीं कर रहा है। प्रारंभ करने के बाद, जब मैं तत्व तक पहुंचने का प्रयास करता हूं, तो यह फू के निजी कन्स्ट्रक्टर को कॉल करने का प्रयास करता है। क्या मैं कुछ भुल गया? अगर मैं उपयोग करता हूं तो यह काम करता है। अगर मैं ऑपरेटर [] initialized मूल्यों तक पहुँचने के लिए इस्तेमाल कर सकते हैं मैं सोच रहा हूँ ...सी ++ 11 मानचित्र शुरू करें

#include <map> 
#include <string> 

class Foo{ 
public: 
    int a, b; 
    Foo(int a_, int b_){ 
     a = a_; 
     b = b_; 
    } 

private: 
    Foo(){}; 
}; 


int main(){ 

    std::map<std::string, Foo> myMap = { {"1", Foo(10,5)}, {"2", Foo(5,10)} }; 
    int b = myMap["1"].b; // it tries to call private constructor of Foo. 
    return 0; 
} 

उत्तर

21

जब आप एक नक्शे पर operator[] उपयोग करते हैं, आप ऑपरेटर का उपयोग कर सकते या तो मानचित्र से एक मूल्य प्राप्त करने के लिए या मानचित्र में एक मान असाइन करें। मानचित्र में मान असाइन करने के लिए, मानचित्र को इसके मान प्रकार का ऑब्जेक्ट बनाना होगा, और संदर्भ द्वारा इसे वापस करना होगा, ताकि आप किसी मौजूदा ऑब्जेक्ट को ओवरराइट करने के लिए operator= का उपयोग कर सकें।

परिणामस्वरूप, प्रकार को डिफ़ॉल्ट रचनात्मक होना चाहिए ताकि आपके लिए असाइन करने के लिए एक नई वस्तु बनाई जा सके।

रन टाइम पर, कन्स्ट्रक्टर को पहले से मौजूद नहीं होने पर बुलाया नहीं जाएगा, लेकिन कंपाइलर को यह जानने का कोई तरीका नहीं है कि आप कभी भी operator[] का उपयोग किसी ऐसे मान तक पहुंचने के लिए करेंगे जो मौजूद नहीं है, इसलिए इसे आवश्यक है सार्वजनिक होने के लिए निर्माता।

+0

स्पष्ट स्पष्टीकरण के लिए धन्यवाद। –

18

नक्शे के operator[] क्योंकि यह एक नई प्रविष्टि अगर एक अस्तित्व में नहीं है बनाता है, डिफ़ॉल्ट constructible होने के लिए प्रकार की आवश्यकता है।

आप at() बजाय जो फेंकता उपयोग कर सकते हैं, अगर प्रविष्टि मौजूद नहीं है:

int b = myMap.at("1").b; 
+0

तथ्य यह है कि इसके लिए निर्माता का अस्तित्व आवश्यक है इसका मतलब यह नहीं है कि अगर यह वस्तु पहले से मौजूद है, तो इसे कॉल करना चाहिए, जो इसे नहीं करना चाहिए। –

+3

@ डेविडरोड्रिगुएज़-ड्राईबीस लेकिन मृत कोड को अभी भी संकलित करना है। –

+5

@ डेविड: सी ++ 11 को वास्तव में 'मानचित्र <> :: ऑपरेटर [] '(§23.4.4.3/2,6) के लिए' डिफ़ॉल्ट कॉन्स्ट्रक्टेबल 'अवधारणा की आवश्यकता होती है। – ildjarn