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?
Live Demo
Your operator is templated, thus the template arguments need to be deduced. You cannot do that, since the compiler tries to match basic_string<_CharT, _Traits, _Alloc>
to your Location
, and it fails.
So the problem is the overloading, not the conversion, since the code actually never reaches that point.
Change this:
std::string s2 = "Line: "s + loc + "\n"s;
to this:
std::string s2 = "Line: "s + std::string(loc) + "\n"s;
and you should be fine, since if you look closely at the compiler error, it mentions:
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
^~~
and other similar messages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With