2011-07-22 22 views
10

Hãy xem xét mã sau đây.Tại sao trình biên dịch không thực hiện chuyển đổi kiểu?

#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; 
} 

Mã này không biên dịch trên g ++ hoặc Microsoft Visual C++. Báo cáo lỗi do trình biên dịch cung cấp là no match for operator '<' in 's < x'. Câu hỏi đặt ra là tại sao trình biên dịch không chỉ đơn giản là chuyển đổi SimpleStruct x thành string theo operator string() nhất định và sau đó sử dụng operator < (string, string)?

Trả lời

13

operator< cho std::string là mẫu chức năng. Quá tải là:

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

Cuộc gọi của bạn không khớp với bất kỳ tình trạng quá tải nào, vì vậy tất cả chúng đều bị xóa khỏi danh sách ứng cử viên. Vì không có mẫu chức năng nào được chọn làm ứng cử viên để giải quyết cuộc gọi, nên không có gì để chuyển đổi SimpleStruct thành.

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, câu trả lời này là chính xác. 'string :: operator <()' không nhận tham số là 'const string &', nhưng 'basic_string <>'; nếu bạn quá tải 'toán tử <' trên toàn cầu thì nó hoạt động. http://www.ideone.com/vMERa – iammilind

+1

Eh, 'std :: string' chỉ là một typedef cho' std :: basic_string '. 'typedef' không giới thiệu một kiểu mới, và do đó không ảnh hưởng đến quá tải. – MSalters

+2

Vấn đề cơ bản là việc khấu trừ 'charT' trong' template toán tử bool <(std :: basic_string const & lhs, std :: basic_string const & rhs); 'không thành công. Không có' charT' mà 'basic_string ' _equals_ 'SimpleStruct' thực sự loại bỏ nó khỏi tập quá tải. – MSalters

Các vấn đề liên quan