1

I used to display an string by std::cout << str << std::endl, and thought an object implicitly convertabel to std::string can be also displayed in this way.

However, I notice that I was wrong. I cannot std::cout an implicitly converted std::string until I overload operator << for std::string.

The following code demonstrates the mentioned stuff.

#include <stdio.h>
#include <iostream>
#include <string>

class X
{
public:
    operator std::string() const {
        return std::string("world");
    }
};

#ifdef OVERLOAD_STREAM_OP
std::ostream& operator<<(std::ostream& os, const std::string& s) {
    return os << s;
}
#endif

int main() {
    std::string s = "hello";
    std::cout << s << std::endl; // viable
    printf("---\n");
    X x;
    std::cout << x << std::endl; // not viable

    return 0;
}

It seems that, in STL implementation, the overloaded operator << function for std::string type, is a little bit different (But I really really don't understand those template stuffs):

  template<typename _CharT, typename _Traits, typename _Allocator>
    std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
           const basic_string<_CharT, _Traits, _Allocator>& __str)
    { return __os << __str._M_base(); }

My questions:

  1. What is the difference between STL's overloaded operator << and my own overloaded operator<< for std::string type?

  2. Why I cannot display the implicitly converted std::string object x with std::cout(compile error)?

1
  • 3
    That OVERLOAD_STREAM_OP bit, how do you think that's legal? You're adding an overload but none of the types are yours. Commented Jun 5, 2021 at 15:07

1 Answer 1

4
  1. What is the difference between STL's overloaded operator << and my own overloaded operator<< for std::string type?

Your operator<< is non-template, while STL's one is template.

  1. Why I cannot display the implicitly converted std::string object x with std::cout(compile error)?

Implicit conversion (from X to std::string) won't be considered in template argument deduction, which makes the invocation on the template operator<< failing. On the other hand, non-template operator<< doesn't have such issue.

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

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.