Ziping Sun
Ziping Sun

Reputation: 61

Why implicit conversion to std::string doesn't work with operator<< being called

At first, I used a user-defined convert function to implicitly convert an object to int and then inserted it to cout with << operator. The program was compiled successfully and printed '0'.

#include <iostream>

using namespace std;

class T {
public:
    operator int () {
        return 0;
    }
};

int main()
{
    T a;
    cout << a << endl;
    return 0;
}

Then, I tried to do the same thing except that the object was converted to a std::string. The program got a compile error.

#include <iostream>
#include <string>

using namespace std;

class T {
public:
    operator string () {
        return "";
    }
};

int main()
{
    T a;
    cout << a << endl;
    return 0;
}

Why implicit conversion doesn't happen on the second case.

Upvotes: 5

Views: 157

Answers (1)

songyuanyao
songyuanyao

Reputation: 172934

Why implicit conversion doesn't happen on the second case.

Because operator<<(std::basic_string) is a template function,

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);

That means given T a; cout << a << endl;, for it to be called, all the three template parameters need to be deduced. But in template argument deduction, implicit conversion won't be considered and then deduction fails.

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

On the other hand, std::basic_ostream::operator<<(int) is a non-template function; it doesn't have such issues.

Upvotes: 9

Related Questions