Consider the following example:
#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
}
The commented line causes a compilation error: no match for 'operator+'. Why? My initial thought was that it would first use operator std::string to convert and then perform the call to operator+, the same way it does for .append.
It is only one level of implicit conversion, so it should be performed and it should be taken into account, no?
s?.append, the template arguments are already instantiated during construction of"Line"s, so there is no template argument deduction taking place (.appendwantsstd::string), but the+operator is templated, so you need to deduceCharT,TraitsandAllocator, and you cannot because the compiler cannot matchbasic_string<...>againstLocation- You don't even reach the conversion phase, it's the overload phase that fails.