2010-08-19 13 views
12

मुझे उम्मीद है कि कोई जवाब दे सकता है कि निम्नलिखित क्यों काम नहीं करता है। हालांकि मेरे साथ सहन, मैं बहुत ज्यादा एक noob अभी भी हूँ ... मैं सिर्फ क्यों निम्नलिखितसी ++ ओवरलोडिंग रूपांतरण ऑपरेटर कस्टम प्रकार से std :: स्ट्रिंग

using namespace std; 
#include <string> 
#include <iostream> 

class testClass 
{ 
public: 
operator char*() {return (char*)"hi";}; 
operator int() {return 77;}; 
operator std::string () {return "hello";}; 
}; 

int main() 
{ 
char* c; 
int i; 
std::string s = "goodday"; 

testClass t; 

c = t; 
i = t; 
s = t; 

cout<< "char: " << c << " int: " << i << " string: "<<s<<endl; 

return 0; 
} 

मुझे एक संकलन समय त्रुटि देता है की तह तक पहुंचने नहीं कर सकते हैं:

myMain.cpp: In function ‘int main()’: 
myMain.cpp:23: error: ambiguous overload for ‘operator=’ in ‘s = t’ 
/usr/include/c++/4.2.1/bits/basic_string.h:500: note: candidates are: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 
/usr/include/c++/4.2.1/bits/basic_string.h:508: note:     std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 
/usr/include/c++/4.2.1/bits/basic_string.h:519: note:     std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 

मैं तो असाइनमेंट

s = t; 

यह काम करता है।

मैं त्रुटि संदेश को समझने के लिए घंटों तक कोशिश कर रहा हूं, लेकिन मुझे सबसे ज्यादा परेशान करने वाला यह है कि यह char * के लिए काम करता है।

मैं किसी भी संकेत के लिए आभारी हूं। धन्यवाद! मार्कस

उत्तर

1

असल में, ऐसा इसलिए है क्योंकि std::string एक असाइनमेंट ऑपरेटर प्रदान करता है जो const char* लेता है।

+1

तो इसका मतलब है कि std :: स्ट्रिंग ऑपरेटर =() और मेरे testClass :: ऑपरेटर std :: स्ट्रिंग() नौकरी के लिए प्रतिस्पर्धा कर रहे हैं? – Markus

+1

@ मार्कस: जैसा कि दूसरों को समझाने के लिए बहुत दयालु थे, असाइनमेंट ऑपरेटर ओवरलोड हो गया है और आपके वर्ग के एक निहित रूपांतरण के प्रकारों में से एक से अधिक संभाल सकता है। –

10

क्या त्रुटि समझाने की कोशिश कर रहा है कि अपने काम "s = t", जहाँ s एक std::string है, तभी मान्य है t एक std::string भी थे, या अगर t एक [const] char* थे होगा। इसलिए संकलक, जिस पर एक दूसरे के ऊपर का चयन करने के कोई आधार नहीं है आपकी रूपांतरण ऑपरेटरों, या तो में एक t परिवर्तित कर सकते हैं .... रूपांतरण का चयन करके

आप इस स्पष्ट को स्पष्ट कर सकते हैं आप चाहते हैं:

s = t.operator std::string(); 
s = static_cast<std::string>(t); 

या आप केवल एक रूपांतरण प्रदान कर सकते हैं और जब आवश्यक हो तो उपयोगकर्ता को आगे रूपांतरण करने दें।

हालांकि आप अंत में पाएंगे - कि किसी भी रूपांतरण ऑपरेटर के मुकाबले ज्यादा परेशानी है ... यह बता रहा है कि std::string स्वयं एक रूपांतरण ऑपरेटर const char* पर प्रदान नहीं करता है।

+0

लेकिन अगर मैं वैरिएबल सी और char * ऑपरेटर समीकरण के बाहर लेता हूं तो यह संकलित नहीं होता है। मैं क्लास टेस्ट क्लास के उपयोगकर्ता द्वारा रिटर्न वैल्यू में अलग-अलग सदस्य कार्यों को ओवरलोड करने में असमर्थता के प्रयास में स्पष्ट असंबद्धता से बचने की कोशिश कर रहा हूं। – Markus

+1

प्रति त्रुटि संदेश के रूप में, तीसरे std :: स्ट्रिंग असाइनमेंट ऑपरेटर अस्पष्टता में शामिल प्रकार "चार" है ... दुर्भाग्य से अपने परीक्षण वर्ग int करने के लिए एक अंतर्निहित रूपांतरण है, और चार सिर्फ एक (आमतौर पर) 8 बिट है std :: स्ट्रिंग :: c_str() इतनी बार फोन करने के लिए नहीं होने कल्पना - - लेकिन दुर्भाग्य से उपलब्ध दृष्टिकोण मुद्दे हैं पूर्णांक .... मैं अपने उद्देश्य के साथ सहानुभूति है ... यह अगर एक अच्छा समाधान अस्तित्व में बहुत अच्छा होगा। हो सकता है कि सी ++ को ऐसी स्थितियों को असंबद्ध करने के लिए एक नोटेशन का समर्थन करना चाहिए - जब प्रोग्रामर को विश्वास है कि सभी मैच कार्यात्मक रूप से समकक्ष हैं - लेकिन अभी के लिए ... :-( –

+0

"कार्यात्मक रूप से समतुल्य" का अर्थ बराबर नहीं है। निर्माण/असाइन करना स्थिरांक std :: तार के साथ स्ट्रिंग और की तुलना में स्थिरांक चार * अधिक कुशल होने की संभावना है (जीसीसी libstdC++ के साथ, यह बफर साझा करता है और करता है कॉपी-ऑन-राइट, मुझे लगता है) भले ही वे अन्यथा एक ही बात करने के लिए दिखाई देते हैं,। –

3

कोई सटीक std :: string :: ऑपरेटर = नहीं है। उम्मीदवारों सम्मान, व्याख्या कर रहे हैं,

s = (const std::string)(std::string)t; 
s = (const char*)t; 
s = (char)(int)t; 

मुझे लगता है कि अगर आप स्थिरांक std :: स्ट्रिंग लौटाने के लिए इसे बदल बातें काम करेंगे। (संपादित करें: मैं गलत हूं।) यह भी ध्यान रखें कि पहले फ़ंक्शन को कॉन्स char * वापस करना चाहिए। यदि आपको char * के लिए एक स्ट्रिंग अक्षरशः डालना है, तो आप कुछ गलत कर रहे हैं; स्ट्रिंग अक्षर लिखने योग्य नहीं हैं।

+0

बस कोशिश की और यह काम नहीं लग रहा है। और संकेत के लिए धन्यवाद। मुझे पता है कि मुझे चीजों के बारे में सोचने और सीखने की जरूरत है ... – Markus

+0

ऑपरेटर std :: string() के साथ कुछ भी गलत नहीं है ... यह स्ट्रिंग अक्षर से अस्थायी std :: स्ट्रिंग बनाता है वह तब कॉलर द्वारा "स्वामित्व" है, इसलिए उस पर कोई भी गैर-कॉन्स्ट ऑपरेशन स्ट्रिंग अक्षर को प्रभावित नहीं करता है। लेकिन यह निश्चित रूप से पहले के लिए ऑपरेटर कॉन्स चार *() होना चाहिए। –

+0

स्पष्ट रूप से मेरा सी ++ - फू खरोंच तक नहीं है। इसे एक कास्ट और असाइनमेंट ऑपरेटर दोनों को चुनना होगा, और इसके लिए ऑपरेटर = (const std :: string &) 'ऑपरेटर = (कॉन्स char *) 'को प्राथमिकता देने के लिए कोई कारण नहीं है। मुझे यकीन नहीं है कि क्या आप वैश्विक असाइनमेंट ऑपरेटर (यानी ':: ऑपरेटर = (std :: string &, const testclass &) 'को परिभाषित कर सकते हैं, लेकिन यदि यह काम करता है, तो यह एक समाधान हो सकता है।) –

9

$13.3.1.5/2 states- "The conversion functions of S and its base classes are considered. Those that are not hidden within S and yield type T or a type that can be converted to type T via a standard conversion sequence (13.3.3.1.1) are candidate functions. Conversion functions that return a cv-qualified type are considered to yield the cv-unqualified version of that type for this process of selecting candidate functions. Conversion functions that return “reference to cv2 X” return lvalues of type “cv2 X” and are therefore considered to yield X for this process of selecting candidate functions."

काम एस = इस प्रकार टी काम करता है:

क) 'टी' (testClass) के प्रकार के विचार कर रहे हैं के सभी सदस्यों को जो 'टी' के लिए परिवर्तित कर सकते हैं 'एस'।

Candidate 1: operator string(); // s created using member string::operator=(string const&) 
Candidate 2: operator char *() // s created using member string::operator=(char const*) 
Candidate 3: operator char *() // s created using member string::operator=(char *) 

ख) के ऊपर उम्मीदवारों के सभी व्यवहार्य (कि अन्य उम्मीदवारों के अभाव में, है, संकलक सफलतापूर्वक सबसे अच्छा उनमें से या तो करने के लिए समारोह कॉल)

ग हल कर सकते हैं) हालांकि, अब व्यवहार्य उम्मीदवार को निर्धारित करना होगा। रूपांतरण शामिल दृश्यों हैं:

Candidate 1: U1 : operator string() 
Candidate 2: U2 : operator char*()->const qualification to match string::operator=(char const*) 
Candidate 3: U3 : operator char*() 

$13.3.3.1.1/3 states - "The rank of a conversion sequence is determined by considering the rank of each conversion in the sequence and the rank of any reference binding (13.3.3.1.4). If any of those has Conversion rank, the sequence has Conversion rank;"

इसका मतलब है कि U1, U2 और U3 सब होने रूपांतरण रैंक कर रहे हैं और एक प्रथम स्तर पर न तो अन्य की तुलना में बेहतर है। हालांकि, मानक भी

User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor and if the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2.

तो, देखते हैं इसका क्या अर्थ है।

U1 और U2 के बीच

, वे शामिल है, अलग-अलग रूपांतरण कार्य करता है और इसलिए कोई भी अन्य

U1 और U3 के बीच तुलना में बेहतर है, वे शामिल विभिन्न रूपांतरण कार्यों और इसलिए कोई भी अन्य की तुलना में

बेहतर है तो यू 1 और यू 2 के बारे में क्या। उनमें एक ही रूपांतरण फ़ंक्शन शामिल है, जो

से अधिक "और" स्थिति के पहले भाग को संतुष्ट करता है तो भाग के बारे में क्या है "और यदि यू 2 का दूसरा मानक रूपांतरण अनुक्रम यू 2 के दूसरे मानक रूपांतरण अनुक्रम से बेहतर है।"

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

लेकिन मानक राज्यों में तालिका 9 के रूप में, सीवी योग्यता को एक सटीक मैच भी माना जाता है।

इसलिए यू 2 और यू 3 वास्तव में अतिसंवेदनशील भी हैं जहां तक ​​ओवरलोड रिज़ॉल्यूशन माना जाता है।

इसका मतलब यह है U1, U2 और U3 हैं सब वास्तव में के रूप में अच्छा एक दूसरे को और संकलक के रूप में अस्पष्ट रूप में (काम के बयान का हिस्सा है) कॉल को हल करने पाता है, के रूप में वहाँ कोई स्पष्ट सबसे अच्छा व्यवहार्य समारोह है

+0

दोस्तों, फ़ॉर्मेटिंग में कठिनाई हो रही है ब्लॉक उद्धरण में चरण (सी)। मदद चाहिए। – Chubsdad

+0

आपको एक अतिरिक्त नई लाइन की आवश्यकता है। – greyfade

+0

@ ग्रेफेड: धन्यवाद दोस्त – Chubsdad

0

ठीक है, बहुत पहले से ही बहुत धन्यवाद। मुझे लगता है कि मैं इसे लटकाना शुरू कर रहा हूं, ...

सबसे पहले मुझे इस तथ्य से अवगत नहीं था कि char सिर्फ 8-बिट int है। उस स्पष्टीकरण के लिए धन्यवाद।

तो मुझे लगता है कि समझते हैं, क्योंकि वहाँ तीन असाइनमेंट ऑपरेटरों std :: स्ट्रिंग, अलग तर्क (स्ट्रिंग, चार *, स्थिरांक चार *) मेरी अभिव्यक्ति के दाएँ हाथ की ओर के साथ प्रत्येक के लिए परिभाषित कर रहे हैं

s=t 

पता नहीं है, किस प्रकार का है में परिवर्तित करने की है, के बाद से वहाँ कई हैं, संभावित मिलान (के लिए यह काम करने के लिए std :: स्ट्रिंग) के साथ निर्धारित रूपांतरण या तो

operator int() {return 77;}; 
operator std::string () {return "hello";}; 

(के बाद से चार: 8 बिट पूर्णांक)

या

operator char*() {return (char*)"hi";}; 
operator std::string () {return "hello";}; 

यह सही है? तो बेवकूफ शब्दों में, असाइनमेंट का बाएं हाथ की ओर दाएं हाथ की तरफ नहीं बता रहा है, जिसकी अपेक्षा है, इसलिए rhs को अपने विकल्पों में से चुनना है, जहां कोई दूसरे के जैसा अच्छा है? std :: स्ट्रिंग ऑपरेटर = मेरे इरादे के लिए सहिष्णु होने वाला है?

अब तक इतना अच्छा है, मैंने सोचा कि मुझे यह मिला - लेकिन फिर, निम्नलिखित अस्पष्टता क्यों बनाते हैं?

using namespace std; 
#include <string> 
#include <iostream> 

class testClass 
    { 
    public: 
    operator float() {return float(77.333);}; 
    operator std::string () {return "hello";}; 
    }; 

    int main() 
    { 
    std::string s = "goodday"; 
    testClass t; 

    s = t; 

    cout<< " string: "<<s <<endl; 

    return 0; 
    } 

अब मेरे द्वारा परिभाषित केवल एक मिलान रूपांतरण ऑपरेटर है, है ना? std :: स्ट्रिंग ऑपरेटर = फ्लोट नहीं ले सकता है, या यह कर सकता है? या किसी भी तरह से फिर से चार प्रकार के बराबर के रूप में तैरता है?

मैं कोड को समझने के रूप में की = 'आरएचएस कह: "मुझे एक स्ट्रिंग, चार * या स्थिरांक चार * देना"

Rhs की जाँच करता है क्या यह testClass का एक उदाहरण दिया प्रदान कर सकते हैं, और केवल मैच testClass :: ऑपरेटर std :: स्ट्रिंग

फिर से, आपके धैर्य, विशेषज्ञता और समय के लोगों के लिए धन्यवाद - मैं वास्तव में इसकी सराहना करता हूं।

+0

ऐसा इसलिए है क्योंकि फ़्लोटिंग-अभिन्न मानक रूपांतरण अनुक्रम के हिस्से के रूप में 'फ़्लोट' को 'char' में परिवर्तित किया जा सकता है। यदि आपको कंपाइलर संदेशों को समझने में कठिनाई है, तो अवधारणा सीखने का एक तरीका है "ऑपरेटर स्ट्रिंग()" पर टिप्पणी करना और कोड में क्या होता है इसकी जांच करना है। वीएस "चेतावनी सी 4244: 'तर्क' देता है: 'फ्लोट' से 'char' में रूपांतरण, डेटा का संभावित नुकसान"। इसका मतलब है कि ऑपरेटर फ्लोट() एक उम्मीदवार है और इस ऑपरेटर को कॉल करने के लिए मैच को फ्लोट से चार – Chubsdad

+0

पर रूपांतरण की आवश्यकता है, इसलिए अभी भी मुझे बहुत कुछ सीखना है। फिर से सभी को धन्यवाद! मुझे लगता है कि, मैंने एक सुरुचिपूर्ण समाधान के रूप में जो सोचा वह सब के बाद काम नहीं करता है ... – Markus

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