एमएसवीएस 2012 में कंपाइलर त्रुटि "ओवरलोडेड फ़ंक्शन पर संदिग्ध कॉल"

I have an Item class that can carry multiple types of data, including a std::map. I have defined operator[] to do the following: if Item is not of type V_MAP (V_MAP is part of an enum where I specify the type carried), Item changes its type to V_MAP. After this "cast", it returns internalMap [ ItemPassedAsArgument ]. The operator has the following declaration:

Item& operator[] (const Item& itemArg);

यह ठीक काम करता है, मैंने विभिन्न तरीकों से परीक्षण किया है।

अब, इसे किसी अन्य सामान के साथ एकीकृत करने की आवश्यकता है, उस सामान में से पहले क्लासएक्स है।

क्लासएक्स में टाइप आइटम (वीएमएपी) का सदस्य है। इसे सामान रखने की जरूरत है। यह (क्लासएक्स) में निम्नानुसार एक सदस्य विधि भी परिभाषित की गई है:

 std::string ClassX::getSmth() const {
    return item[keySmth];
}

जहां keySmth है

const std::string ClassX::keySmth ("blablabla");

मुझे getSmth() METHOD की परिभाषा को बदलने की अनुमति नहीं है। उस कॉन्स को वहां रहने की जरूरत है, उस विधि को केवल चीजों का निरीक्षण करना चाहिए।

जैसा कि आप देख सकते हैं, विधि कुछ भी नहीं बदल सकती है, इसलिए यह मेरे ऑपरेटर के साथ विरोधाभास करता है। इस तरह इस्तेमाल होने पर, त्रुटि ने कहा कि कोई ऑपरेटर [] इन ऑपरेटरों से मेल खाता है। ऑपरेशंस कॉन्स आइटम [const std :: string] हैं। इसलिए, मैंने ऑपरेटर [] को लगभग उसी चीज़ को करने के लिए ओवरलोड किया है, उस भाग को छोड़कर जहां यह आइटम के प्रकार को बदलता है, और एक कॉन्स <कोड> आइटम लौटाता है । यह घोषणा है:

const Item& operator[] (const Item& itemArg) const;

अब यह सुनिश्चित करने के लिए प्रोग्रामर पर निर्भर है कि सबस्क्रिप्ट ऑपरेटर अब केवल आइटम प्रकार V_MAP के प्रकार पर लागू होता है।

लेकिन अब मुझे निम्नलिखित कंपाइलर त्रुटि मिलती है:

error C2668: 'std::basic_string<_Elem,_Traits,_Alloc>::basic_string' : ambiguous call to overloaded function 

      with
      [
          _Elem=char,
          _Traits=std::char_traits,
          _Alloc=std::allocator
      ]

      c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstring(896): could be 'std::basic_string<_Elem,_Traits,_Alloc>::basic_string(std::basic_string<_Elem,_Traits,_Alloc> &&) throw()'

      with
      [
          _Elem=char,
          _Traits=std::char_traits,
          _Alloc=std::allocator
      ]
      c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstring(789): or       'std::basic_string<_Elem,_Traits,_Alloc>::basic_string(const _Elem *)'

      with
      [
          _Elem=char,
          _Traits=std::char_traits,
          _Alloc=std::allocator
      ]

      while trying to match the argument list '(const Item)'

समस्या कहाँ हे? धन्यवाद

संपादित करें: यह std :: स्ट्रिंग के लिए निर्माता है:

Item(const std::string str_value) {
    m_data = new Data (str_value);
    m_type = V_STR;
}

std::string from Item:

template
operator T() const {
    //Check
    if (this->m_data == nullptr)
        return NULL;
   //dynamic_cast m_data to point to "an Item of type T"
    Data* temp_data = dynamic_cast* > (m_data);
    return temp_data->m_dataOfAnyType;
}
0
आप एक आइटम से std :: string कैसे बनाते हैं? Revelant कोड भाग Thats।
जोड़ा लेखक Sebastian Hoffmann, स्रोत
हमें std :: string को आइटम पर आइटम की आवश्यकता नहीं है std :: string
जोड़ा लेखक Sebastian Hoffmann, स्रोत
मैंने सवाल संपादित किया है, आप इसके अंत में निर्माता ढूंढ सकते हैं
जोड़ा लेखक Hame, स्रोत
क्षमा करें, बहुत तेज़ी से पढ़ना: पी
जोड़ा लेखक Hame, स्रोत

1 उत्तर

इसका कारण यह है कि यह आपके कास्ट ऑपरेटर के कारण है, जो कि किसी भी चीज़ में आइटम डाल सकता है (कम से कम आपको यह देखना चाहिए था कि यह अति महत्वाकांक्षी है)।

एक std :: string कॉपी कन्स्ट्रक्टर के माध्यम से या एक चार सूचक के माध्यम से बनाया जा सकता है (दोनों में केवल 1 पैरामीटर है, कुछ और रचनाकार हैं लेकिन ये इसके लिए अप्रासंगिक हैं)। इस मामले में संकलक को पता नहीं है कि उसे आइटम ऑब्जेक्ट को char * या std :: string पर बनाने के लिए एक स्ट्रिंग (ध्यान दें कि जब आप मूल्य से वापस आते हैं, तो अस्थायी बनाया जाता है)।

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

एक और संभावना यदि आप उस ऑपरेटर को बनाए रखना चाहते हैं तो एक toString() विधि को परिभाषित करना है जो किसी भी तरह से आईएमओ को निहित कास्टिंग से बहुत साफ है।

तीसरी संभावना है कि आप अपने आइटम को स्पष्ट रूप से डालें। फिर आप लिख सकते हैं:

return (std::string) item;
// or
return (char*) item;
3
जोड़ा
std :: string foo (itemObj) लिखने का प्रयास करें;
जोड़ा लेखक Sebastian Hoffmann, स्रोत
लेकिन जब मैंने आइटम की कार्यक्षमता का परीक्षण किया है, तो मैंने एक testString (std :: string testStr) लिखा है; जिसमें मैं एक आइटम (V_STR) पास करता हूं , और यह ठीक काम करता है
जोड़ा लेखक Hame, स्रोत
हा हा बड़िया। वही त्रुटि ठीक है, मैं एक toString() विधि लिखूंगा।
जोड़ा लेखक Hame, स्रोत