2017-10-20 66 views
5

Hãy xem xét ví dụ sau:điều hành chuyển đổi ngầm định không đá với nhà khai thác quá tải

#include <string> 
#include <sstream> 

struct Location { 
    unsigned line; 

    template<typename CharT, typename Traits> 
    operator std::basic_string<CharT, Traits>() const { 
    std::basic_ostringstream<CharT, Traits> ss; 
    ss << line; 
    return ss.str(); 
    } 
}; 

int main() 
{ 
    using namespace std::string_literals; 

    Location loc{42}; 

    std::string s1 = "Line: "s.append(loc) + "\n"s; // fine 
    //std::string s2 = "Line: "s + loc + "\n"s; // error 
} 

Điểm mấu nhận xét gây ra một lỗi biên dịch: no match for 'operator+'. Tại sao? Suy nghĩ ban đầu của tôi là lần đầu tiên nó sẽ sử dụng operator std::string để chuyển đổi và sau đó thực hiện cuộc gọi đến operator+, tương tự như vậy đối với .append.

Nó chỉ là một cấp độ chuyển đổi tiềm ẩn, vì vậy nó cần được thực hiện và cần được tính đến, phải không?

Live Demo

+0

Xin lỗi vì đã hỏi, nhưng tôi không thấy nhận mã làm việc. 'S' là gì? – gsamaras

+3

@gsamaras http://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s – Holt

+0

Đúng @Holt, cảm ơn! – gsamaras

Trả lời

2

điều hành của bạn là templated, do đó các đối số mẫu cần phải được suy luận. Bạn không thể làm điều đó, vì trình biên dịch cố gắng kết hợp basic_string<_CharT, _Traits, _Alloc> với số Location của bạn và không thành công.

Vì vậy, vấn đề là quá tải, không phải chuyển đổi, vì mã thực sự không bao giờ đạt đến điểm đó.

Thay đổi này:

std::string s2 = "Line: "s + loc + "\n"s; 

này:

std::string s2 = "Line: "s + std::string(loc) + "\n"s; 

và bạn nên sử dụng tốt, vì nếu bạn nhìn kỹ vào những lỗi biên dịch, nó đề cập đến:

template argument deduction/substitution failed: 
prog.cc:22:32: note: 'Location' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>' 
    std::string s2 = "Line: "s + loc + "\n"s; // error 
           ^~~ 

và các tin nhắn tương tự khác.

0

Explicit cast để std :: string làm việc cho tôi: https://godbolt.org/g/WZG78z

std::string s2 = "Line: "s + std::string(loc) + "\n"; // was error 
Các vấn đề liên quan