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?
It is a special kind of an istream that reads in data from a data file. ofstream is an output file stream. It is a special kind of ostream that writes data out to a data file.
What is STREAM? STREAM is an offshoot of STEM- Science, Technology, Engineering, and Mathematics. It is a cross-curricular style of educating that engages students and allows a higher level of learning to occur.
The class ofstream is used for output to a file. Both of these classes are defined in the standard C++ library header fstream .
Whenever there is a need to represent the output file stream and to create a file and write information to the file, we make use of ofstream by including the header file <fstream> in the source file. Ofstream is derived from the class ostream class.
When you call
os << t.y;
you have 2 candidates:
ostream& operator << (ostream&, int) //1
and
ofstream& operator << (ofstream&, Test) //2
There is no such candidate as
ofstream& operator << (ofstream&, int) //3
According to the overload resolution rules, neither 1 nor 2 is better for your call. Hence the warning. In case of ostream
, 1 is obviously a better match, because both arguments match exactly.
The best solution is to go with std::ostream
. Why would you need to overload specifically for file streams. What if you need to stream it into a string? Overload output stream operator for std::ostream
(or even a templatized version of std::basic_ostream
) and let the compiler handle the rest.
As the warning tells you, with ofstream
both interpretations require conversions:
ofstream& -> ostream&
in static_cast<ostream&>(os) << t.y
,
int -> Test
in os << static_cast<Test>(t.y)
If you use ostream&
directly, then the int
-interpretation requires no conversion and hence is preferred.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With