Reputation: 61
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
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