This is not important. But I’m curious as to when this warning appears. My real question is why ostream and ofstream are treated differently.
struct Test {
int y;
Test(int k) : y(k) {}
};
With this simple struct, the compiler sees that an int can be converted to a Test.
Therefore, I get a warning with this code:
std :: ofstream& operator<< (std :: ofstream& os, const Test& t)
{
os << t.y;
return os;
}
When it sees os << t.y it doesn’t know whether I want to push the int called t.y, or whether I want to convert the int to a Test first and then push it. This seems pretty weird, you’d think it’d prefer the non-converted int overload ofstream& operator<< (ofstream &os, int).
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3:
template_expl.cpp: In function ‘std::ofstream& operator<<(std::ofstream&, const Test&)’:
template_expl.cpp:15: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
/usr/include/c++/4.4/bits/ostream.tcc:105: note: candidate 1: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
template_expl.cpp:13: note: candidate 2: std::ofstream& operator<<(std::ofstream&, const Test&)
Anyway, one way to resolve this is to mark the constructor in Test as explicit. I can live with that. But the weird thing is that if ofstream is replaced with ostream, then the warning goes away. Any idea why?
As the warning tells you, with
ofstreamboth interpretations require conversions:ofstream& -> ostream&instatic_cast<ostream&>(os) << t.y,int -> Testinos << static_cast<Test>(t.y)If you use
ostream&directly, then theint-interpretation requires no conversion and hence is preferred.