2011-07-22 25 views
10

निम्नलिखित कोड पर विचार करें।संकलक एक प्रकार का रूपांतरण क्यों नहीं करता है?

#include <iostream> 
#include <string> 

struct SimpleStruct 
{ 
    operator std::string() { return value; } 
    std::string value; 
}; 

int main() 
{ 
    std::string s; // An empty string. 
    SimpleStruct x; // x.value constructed as an empty string. 

    bool less = s < x; // Error here. 
    return 0; 
} 

यह कोड या तो g ++ या Microsoft Visual C++ पर संकलित नहीं करता है। कंपाइलर्स द्वारा दी गई त्रुटि रिपोर्ट no match for operator '<' in 's < x' है। सवाल क्यों संकलक बस SimpleStruct xstring में नहीं बदलता के अनुसार है operator string() दिया और फिर operator < (string, string) का उपयोग करें?

उत्तर

13

std::string के लिए operator< एक समारोह टेम्पलेट है। भार के हैं:

template<class charT, class traits, class Allocator> 
    bool operator< (const basic_string<charT,traits,Allocator>& lhs, 
      const basic_string<charT,traits,Allocator>& rhs); 
    template<class charT, class traits, class Allocator> 
    bool operator< (const basic_string<charT,traits,Allocator>& lhs, 
      const charT* rhs); 
    template<class charT, class traits, class Allocator> 
    bool operator< (const charT* lhs, 
      const basic_string<charT,traits,Allocator>& rhs); 

आपका कॉल उपलब्ध भार के में से किसी से मेल नहीं खाता, ताकि उन सभी उम्मीदवारों की एक सूची से हटा दिया जाता है। चूंकि कॉल को हल करने के लिए उम्मीदवार के रूप में कोई फ़ंक्शन टेम्पलेट नहीं चुना गया था, इसलिए सरल संरचना को परिवर्तित करने के लिए कुछ भी नहीं है।

template <class T> 
class String 
{ 
}; 

template <class T> 
bool operator< (const String<T>&, const String<T>&) { return true; } 


//if a suitable non-template function is available, it can be picked 
//bool operator< (const String<char>&, const String<char>&) { return true; } 

struct SimpleStruct 
{ 
    operator String<char>() { return value; } 
    String<char> value; 
}; 

int main() 
{ 
    String<char> s; 
    SimpleStruct ss; 
    s < ss; //the call doesn't match the function template, leaving only the commented-out candidate 
} 
+1

+1, यह उत्तर सही है। 'स्ट्रिंग :: ऑपरेटर <()' तर्क को 'कॉन्स्ट स्ट्रिंग' के रूप में नहीं लेता है, लेकिन 'basic_string <>'; यदि आप वैश्विक स्तर पर 'ऑपरेटर <' ओवरलोड करते हैं तो यह काम करता है। http://www.ideone.com/vMERa – iammilind

+1

एह, 'std :: string' सिर्फ std :: basic_string ' के लिए एक टाइपिफ़ है। 'typedef' एक नया प्रकार पेश नहीं करता है, और इसलिए ओवरलोडिंग को प्रभावित नहीं करता है। – MSalters

+2

अंतर्निहित समस्या यह है कि 'टेम्पलेट <कक्षा charT, कक्षा tr, कक्षा एलोक> बूल ऑपरेटर <(std :: basic_string const & lhs, std :: basic_string const & rhs); 'विफल रहता है। 'charT'' नहीं है जिसके लिए' basic_string '_equals_' SimpleStruct' है। यह वास्तव में ओवरलोड सेट से हटा देता है। – MSalters

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