2011-07-22 10 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 xoperator string()に従ってstringに変換してからoperator < (string, string)を使用するのはなぜですか?

答えて

13

operator<std::stringは、関数テンプレートです。オーバーロードは、以下のとおりです。

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); 

あなたの通話が可能なオーバーロードのいずれとも一致しないので、それらはすべての候補者のリストから削除されます。関数テンプレートは呼び出しを解決する候補として選択されていないため、SimpleStructを変換するものはありません。

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この回答は正しいです。 'string :: operator <()'は 'const string&'ではなく 'basic_string <>'として引数をとります。 'operator <'をグローバルにオーバーロードすると、それは動作します。 http://www.ideone.com/vMERa – iammilind

+1

'std :: string'は' std :: basic_string 'の単なるtypedefです。 'typedef'は新しい型を導入しないので、オーバーロードには影響しません。 – MSalters

+2

基本的な問題は、 'template bool operator <(std :: basic_string const&lhs、std :: basic_string const & rhs); 'が失敗します。' basic_string '_equals_' SimpleStruct'の 'charT'はありません。実際には、それをオーバーロードセットから削除します。 – MSalters

関連する問題