2017-10-20 118 views
5

考慮下面的例子踢:隱式轉換操作符不符合操作符重載

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

的註釋行會導致一個編譯錯誤:no match for 'operator+'。爲什麼?我最初的想法是,它將首先使用operator std::string進行轉換,然後執行與operator+的呼叫,方式與.append相同。

它只是一個隱式轉換級別,所以它應該被執行並且應該被考慮到,否?

Live Demo

+0

對不起,但我看不到工作代碼。什麼是's'? – gsamaras

+3

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

+0

Right @Holt,謝謝! – gsamaras

回答

2

您的運營商是模板化,從而需要推導模板參數。你不能這樣做,因爲編譯器試圖將basic_string<_CharT, _Traits, _Alloc>Location匹配,並且失敗。

所以問題是重載,而不是轉換,因爲代碼實際上從來沒有達到這一點。

更改此:

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

這樣:

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

,你應該是很好的,因爲如果你在編譯器錯誤仔細一看,它提到:

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 
           ^~~ 

和其他類似的消息。