Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

warning about ambiguous for ofstream, but not for ostream. What's the difference?

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?

like image 497
Aaron McDaid Avatar asked Dec 19 '11 16:12

Aaron McDaid


People also ask

What is the difference between Ostream and ofstream?

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 does ofstream stand for?

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.

What library is ofstream?

The class ofstream is used for output to a file. Both of these classes are defined in the standard C++ library header fstream .

Is ofstream a header file?

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.


2 Answers

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.

like image 58
Armen Tsirunyan Avatar answered Oct 22 '22 14:10

Armen Tsirunyan


As the warning tells you, with ofstream both interpretations require conversions:

  1. ofstream& -> ostream& in static_cast<ostream&>(os) << t.y,

  2. 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.

like image 40
Kerrek SB Avatar answered Oct 22 '22 14:10

Kerrek SB