2017-10-20 83 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 
           ^~~ 

和其他类似的消息。