2016-12-02 17 views
5

मुझे उन स्थितियों को समझने में कुछ परेशानी हो रही है, जिनमें सी ++ एक अंतर्निहित रूपांतरण का उपयोग करेगा। मान लीजिए मैं एक वर्ग है:सी ++ मानक ऑपरेटरों के लिए ऑपरेटरों में अंतर्निहित रूपांतरण

class SomeClass 
{ 
private: 
    int val; 
public: 
    SomeClass(int i) :val{ i } {} 
    operator string() { return to_string(val); } 
}; 

यह क्यों है कि जब ऑपरेटरों मैं स्ट्रिंग के लिए कास्ट करने के लिए की जरूरत के साथ इस वर्ग का उपयोग कर? यह सिर्फ रूपांतरण को निष्पादित क्यों नहीं करता है?

कोड:

int main(void) 
{ 
    SomeClass sc = 4; 
    cout << (string)sc << endl; //prints 4, compiles fine 
    cout << sc << endl;//does not compile, no operator "<<" matches these operands 

    string str1 = sc;//compiles fine, performs cast 
    string str2 = "Base String" + sc;//does not compile, no operator "+" matches these operands 
} 

यह सवाल व्यावहारिक से अधिक शैक्षिक सिर्फ एक डाली का उपयोग कर के रूप में है वैसे भी अधिक पठनीय है।

उत्तर

2

operator<< overload कि इस्तेमाल किया जाता है जब आप cout << (string)sc बारे में एक समारोह टेम्पलेट है:

template <class CharT, class Traits, class Allocator> 
std::basic_ostream<CharT, Traits>& 
    operator<<(std::basic_ostream<CharT, Traits>& os, 
       const std::basic_string<CharT, Traits, Allocator>& str); 

इसका कारण यह है std::string अपने आप में एक वर्ग टेम्पलेट है, और char के अलावा अन्य प्रकार के साथ instantiated जा सकती है, और यदि वर्ण उसी वर्ण प्रकार की धारा में लिखे गए हैं तो भी प्रिंट करने योग्य होना चाहिए। वास्तव में, यह std::wstring के साथ बिल्कुल होता है, जहां CharTchar के बजाय wchar_t है। वही operator<< काम करता है, बशर्ते आप एक उपयुक्त स्ट्रीम का उपयोग करें।

जब आप cout << sc लिखते हैं, तो उस विशेष अधिभार को माना जाता है। यही कारण है कि अधिभार तो अस्वीकार कर दिया है, क्योंकि संकलक किस प्रकार CharT और दूसरों के लिए उपयोग करने के लिए अनुमान नहीं कर सकते। यह केवल प्रकार अनुमान करने में सक्षम है, तो यह पहले से ही जानते थे कि रूपांतरण प्रदर्शन किया जा सकता है, लेकिन रूपांतरण बस अभी तक, वे केवल एक थोड़ा बाद के चरण में जाँच की जाएगी विचार नहीं किया जाता होगा।

यदि कोई गैर-टेम्पलेट operator<< ओवरलोड था जो std::string लिया गया था, तो यह काम करेगा, sc निहित रूप से परिवर्तित हो जाएगा।

+0

तो फिर, सी ++ मानक लाइब्रेरी फ़ंक्शंस (बिना बगैर) के साथ अधिक संगत होने के लिए, मुझे 'basic_string' पर निहित रूपांतरण लिखना चाहिए और स्ट्रिंग नहीं करना चाहिए? –

+0

@ApoorvaKharche No, 'string'' basic_string' के एक विशेष तत्कालता के लिए एक टाइपिफ़ है। चाहे 'ऑपरेटर <<' 'basic_string 'के संदर्भ में लिखा गया हो या' स्ट्रिंग' के संदर्भ में कोई फर्क नहीं पड़ता है, क्योंकि उनका मतलब एक ही चीज़ है। चाहे 'ऑपरेटर <<' 'basic_string ' या 'basic_string 'के संदर्भ में लिखा गया है, जहां' टी' को कम किया जाना है, इससे कोई फर्क पड़ता है, और आपके पास अपनी कक्षा से इसका कोई नियंत्रण नहीं है। – hvd

2

std::coutstd::string स्वीकार नहीं करता है।
यह एक टेम्प्लेटेड std::basic_string स्वीकार करता है, जिनमें से मापदंड हैं निष्कर्ष निकाला जा सकता है। अधिक जानकारी के लिए
here देखें।

के निम्नलिखित उदाहरण पर विचार करें:

#include<string> 

struct SomeClass { 
    operator std::string() { return ""; } 
}; 

template <class CharT, class Traits, class Allocator> 
void f(const std::basic_string<CharT, Traits, Allocator> &) {} 

template <class CharT, class Traits, class Allocator> 
void f(std::basic_string<CharT, Traits, Allocator> &) {} 

int main(void) { 
    SomeClass sc{}; 
    f((std::string)sc); 
    //f(sc); 
} 

यह है कि आपके मामले में होता है के समान है।
बेशक, f(sc) लगभग उसी कारण के लिए संकलित नहीं करता है।

समस्या यह है कि टेम्पलेट पैरामीटर SomeClass को कम करने के लिए std::string में परिवर्तित किया जाना चाहिए। इसे std::string में परिवर्तित करने में सक्षम होने के लिए, संकलक को अनुमान लगाया जाना चाहिए कि एक वैध अधिभार मौजूद है और इसका उपयोग करने का प्रयास करें। वैसे भी, इस तरह के व्यवहार्य कार्य अपने दृष्टिकोण से मौजूद नहीं है, क्योंकि टेम्पलेट पैरामीटर अभी भी कम किए जा रहे हैं और उन्हें कम करने के लिए संकलक को अनुमान लगाया जाना चाहिए कि SomeClass के लिए एक अधिभार एक कलाकार के बाद मौजूद है। यह नहीं कर सकता, क्योंकि ... और इसी तरह।

मैं इसे की जाँच नहीं की है, लेकिन मुझे यकीन है होता है कि कुछ इसी तरह operator+ को भी लागू होता है।

+0

वास्तव में डाउनवोट के लिए क्या है? – skypjack

+0

तो फिर, सी ++ मानक लाइब्रेरी फ़ंक्शंस (बिना जानवरों के) के साथ अधिक संगत होने के लिए, मुझे 'basic_string' पर निहित रूपांतरण लिखना चाहिए और स्ट्रिंग नहीं करना चाहिए? –

+0

इस उत्तर के कुछ समय बाद, संपादन इतिहास ने ऐसा लगता है कि आपने मूल रूप से मेरी प्रतिलिपि बनाई है, लेकिन संपादन इतिहास भ्रामक था। आपने गलत जवाब पोस्ट किया है, इसे हटाए जाने पर इसे हटा दिया है, और इसे ठीक करने के लिए समाप्त हो गया है। अंत में, हमने मूल रूप से एक ही समय में मूल रूप से एक ही उत्तर पोस्ट किया। अगर ऐसा होना चाहिए तो किसी ने इसे कम किया है, तो उस व्यक्ति को डाउनवोट वापस करने दें। – hvd

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