4

Consider the following struct with a user-defined conversion function that can convert itself to const char*;

struct S {
  operator const char*() { return "hello"; }
};

This work with <iostream>, we can print the struct S with no error message:

std::cout << S{} << '\n';

But if I change the return type to std::string:

struct S {
  operator std::string() { return "hello"; }
};

I got this compiler error message:

<source>:11:13: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'S')
11 |   std::cout << S{} << '\n';
   |   ~~~~~~~~~ ^~ ~~~
   |        |       |
   |        |       S
   |        std::ostream {aka std::basic_ostream<char>}
    <source>:11:18: note:   'S' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
11 |   std::cout << S{} << '\n';
   |                  ^

Why can't the compiler use the std::string conversion? Is there a difference between the conversion function of the built-in and class type?

1 Answer 1

5

Because operator<< for std::basic_string is a template taking 3 template parameters:

template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
    operator<<(std::basic_ostream<CharT, Traits>& os,
               const std::basic_string<CharT, Traits, Allocator>& str);

And implicit conversion won't be considered in template argument deduction:

Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.

Then given std::cout << S{};, the template parameter CharT, Traits and Allocator can't be deduced on the 2nd function argument.

On the other hand, operator<< for const char* doesn't have such issue; given std::cout << S{};, the template parameter CharT and Traits would be deduced only from the 1st function argument. After deduction, the implicit conversion from S to const char* will be performed and the calling works well.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.