Implicit conversion operator does not face operator overloading

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+' . What for? Initially, I thought that I would first use operator std::string to convert, and then make a call to operator+ , just like for .append .

This is only one level of implicit conversion, so it must be done and it should be taken into account, no?

Live demo

+5
source share
2 answers

Your statement is templated, so template arguments must be inferred. You cannot do this because the compiler is trying to map basic_string<_CharT, _Traits, _Alloc> to your Location , and it does not work.

So the problem is overloading, not conversion, because the code actually never reaches that point.

Change this:

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

:

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

and everything should be fine, because 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.

+2
source

The explicit cast to std :: string works for me: https://godbolt.org/g/WZG78z

  std::string s2 = "Line: "s + std::string(loc) + "\n"; // was error 
0
source

Source: https://habr.com/ru/post/1272764/


All Articles