2013-03-13 6 views
11

में ठीक काम करता है। मैं विजुअल स्टूडियो 2012 का उपयोग करने के लिए विजुअल स्टूडियो 2005 के साथ एक पुरानी परियोजना को अपडेट करने की कोशिश कर रहा हूं, और मैं मुझे एक त्रुटि मिल रही है जिसे मैं हल नहीं कर सकता।सी ++ टाइप कास्ट ऑपरेटर कोड जो विजुअल स्टूडियो 2012 में संकलित नहीं होगा, लेकिन विजुअल स्टूडियो 2005

कोड है कि VS2005 के तहत ठीक काम करता है:

#include <iostream> 
#include <string> 
#include <sstream> 

using std::cout; 
using std::wcout; 
using std::endl; 
using std::wstring; 
using std::string; 


class Value 
{ 
public: 
    Value(const wstring& value) 
    { 
     v = value; 
    } 

    Value(Value& other) 
    { 
     this->v = other.v; 
    } 

    template<typename T> 
    operator T() const 
    { 
     T reply; 
     std::wistringstream is; 
     is.str(v); 
     is >> reply; 
     return reply; 
    } 

    operator wstring() const 
    { 
     return v; 
    } 


private: 
    wstring v; 
}; 


int main() 
{ 
    Value v(L"Hello World"); 

    wstring str = v; 
    wcout << str << endl; 

    Value int_val(L"1"); 
    int i = int_val; 

    cout << i + 1 << endl; 

    return 0; 
} 

जब मैं VS2012 के तहत इस संकलन कर रहा हूँ मैं लाइन पर कोई त्रुटि मिलती है "str wstring = वी,", त्रुटि है:

error C2440: 'initializing' : cannot convert from 'Value' to 'std::basic_string<_Elem,_Traits,_Alloc>' 
1>   with 
1>   [ 
1>    _Elem=wchar_t, 
1>    _Traits=std::char_traits<wchar_t>, 
1>    _Alloc=std::allocator<wchar_t> 
1>   ] 
1>   No constructor could take the source type, or constructor overload resolution was ambiguous 

मैं ऑपरेटर हस्ताक्षर को 'ऑपरेटर wstring() const' से 'ऑपरेटर कॉन्स wstring &() const' से ऑपरेटर हस्ताक्षर बदलकर इसे ठीक कर सकता हूं। लेकिन मूल कोड क्यों काम नहीं करता है, भले ही यह वीएस2005 में काम करता है।

मुझे "int i = int_val" पंक्ति पर कोई त्रुटि नहीं मिल रही है।

यह सिग्विन (संस्करण 4.5.3) में जीसीसी (जी ++) के साथ भी संकलित और चलाता है।

अद्यतन वास्तव में मेरी असली समस्या का अनुकरण करने के लिए उपरोक्त नमूना कोड में कुछ जानकारी छोड़ी गई थी। वैल्यू क्लास और उपयोग के बीच कुछ अन्य वर्ग हैं। एक यह है कि इस तरह दिखेगा:

class Config 
{ 
public: 
    virtual Value getValue(const string& key) const = 0; 

    Value operator()(const string& key) 
    { 
     return getValue(key); 
    } 
}; 

और उपयोग स्थिरांक wstring मान 2 = config ("कुंजी");

यह संकलन करते समय उपरोक्त त्रुटि देगा, लेकिन इंटेलिसेन्स भी गलत संकेतों पर अन्य संकेत देगा और यह कहता है: "मूल्य" से "एक से अधिक उपयोगकर्ता परिभाषित रूपांतरण" std :: wstring "पर लागू होता है:" और यह नियमित कन्स्ट्रक्टर और मूल_स्ट्रिंग के चालक कन्स्ट्रक्टर दोनों पर इंगित करता है। ऐसा लगता है कि ऐसा करने के लिए राजस्व के साथ कुछ करना है और मैं उस पर पढ़ रहा हूं, और मूल बातें समझता हूं। लेकिन शायद मुझे बहुत कुछ याद आ रहा है।

मुझे लगता है कि मैं करने के लिए उपयोग को बदलने के द्वारा इस समस्या को ठीक कर सकते हैं: स्थिरांक wstring & & मूल्य = config ("कुंजी");

फिर ऐसा लगता है कि वीएस2012 कंपाइलर समझता है कि इसे किस कन्स्ट्रक्टर का उपयोग करना चाहिए।

प्रश्न: * क्या इस उदाहरण में & & का उपयोग करने का कोई तरीका नहीं है? * वास्तव में क्या हो रहा है? साथ सी ++ 11 https://github.com/Discordia/ImplicitTypeConversion

+3

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

+0

@Xeo: या एकाधिक कंपाइलरों में एक आम बग। मानक में एक त्वरित कर्सर देखो पर * ऐसा लगता है कि वीएस यहां सही हो सकता है। मुझे कोई नियम नहीं मिला जो निर्धारित करता है कि गैर-टेम्पलेट संस्करण को टेम्पलेटेड पर प्राथमिकता दी जाती है, और उस प्राथमिकता के बिना रूपांतरण ऑपरेटर अस्पष्ट होता है जब 'std :: wstring' में परिवर्तित होता है और मानक को कोड विफल होने की आवश्यकता होती है। –

+0

@ डेविड: '§13.3.3/1:' "इन परिभाषाओं को देखते हुए, एक व्यवहार्य कार्य 'F1' को एक अन्य व्यवहार्य फ़ंक्शन ' F2' से बेहतर कार्य माना जाता है यदि [...]' F1' एक है गैर-टेम्पलेट फ़ंक्शन और 'F2' एक फ़ंक्शन टेम्पलेट विशेषज्ञता है [...] " – Xeo

उत्तर

1

सरल में (उम्मीद सरलीकृत नहीं) नियम,, आप lvalue और rvalue के संदर्भ में संदर्भ के बारे में सोच शुरू करने के लिए होगा:

मैं GitHub पर नमूना कोड डाल दिया। असल में, सी ++ 11 आपको "अस्थायी" ऑब्जेक्ट से निपटने के आधार पर अलग-अलग संदर्भों पर संचालन को संभालने की क्षमता देता है। यह आपको विभिन्न स्थितियों में प्रतिलिपि बनाने के बजाय अपने ऑब्जेक्ट में डेटा को आंतरिक स्थानांतरित करने जैसी चीजों को करने की क्षमता देता है। इसका नकारात्मक पक्ष वह प्रभाव है जिसे आप देख रहे हैं, जहां पुराना कोड पर्याप्त विशिष्ट नहीं है जिसके बारे में आप काम कर रहे हैं। इससे इसके लिए और भी कुछ है, यह वास्तव में ऐसा कुछ नहीं है जिसे संक्षिप्त एसओ उत्तर में पूरी तरह समझाया जा सके, लेकिन पिछले answers ने कुछ good places शुरू करने के लिए दिया था। मैं आपके कोड को दोनों रावल्यू और लैवल्यू ऑपरेटरों को प्रदान करने के लिए पुन: कार्य करूंगा (जो ऐसा लगता है जैसे आप पहले से ही करने के अपने रास्ते पर हैं)।

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