By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,701 Members | 1,966 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,701 IT Pros & Developers. It's quick & easy.

compilation error using ofstream

P: n/a
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:

// main()
....
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
....

main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1

Thank you all!



Sep 26 '07 #1
Share this Question
Share on Google+
15 Replies


P: n/a
aaragon wrote:
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:

// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...

main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1
I don't see any "Domain.h" or types called 'Domain' in your code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 26 '07 #2

P: n/a
On Sep 26, 2:41 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
aaragon wrote:
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:
// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...
main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1

I don't see any "Domain.h" or types called 'Domain' in your code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Well, I overloaded operator<< to produce the output of a class that I
designed. But shouldn't the compiler deduct this from the type being
passed to operator<<???? Why is it the call ambiguous????

Sep 26 '07 #3

P: n/a
aaragon wrote:
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:

// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...

main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1

Thank you all!


a minimal version of your program compiles and creates a file contianing
'hello ' after running:

#include <fstream>

int main()
{
std::ofstream fout;
fout.open("hello.out");
fout<<"hello ";
fout.close();
return 0;
}

did you include the first line in your code?

Sep 26 '07 #4

P: n/a
aaragon wrote:
On Sep 26, 2:41 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>aaragon wrote:
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:
// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...
main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1

I don't see any "Domain.h" or types called 'Domain' in your code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Well, I overloaded operator<< to produce the output of a class that I
designed. But shouldn't the compiler deduct this from the type being
passed to operator<<???? Why is it the call ambiguous????
How are we supposed to know? Please, post a _complete_ (but minimal) program
that exhibits the problem (see the FAQ on how-to-post).
Best

Kai-Uwe Bux
Sep 26 '07 #5

P: n/a
"aaragon" <al**************@gmail.comwrote in message
news:11**********************@22g2000hsm.googlegro ups.com...
On Sep 26, 2:41 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>aaragon wrote:
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:
// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...
main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1

I don't see any "Domain.h" or types called 'Domain' in your code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Well, I overloaded operator<< to produce the output of a class that I
designed. But shouldn't the compiler deduct this from the type being
passed to operator<<???? Why is it the call ambiguous????
Does Domain perhaps accept a char* as a constructor?
Sep 26 '07 #6

P: n/a
On Sep 26, 3:14 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
"aaragon" <alejandro.ara...@gmail.comwrote in message

news:11**********************@22g2000hsm.googlegro ups.com...
On Sep 26, 2:41 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
aaragon wrote:
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:
// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...
main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1
I don't see any "Domain.h" or types called 'Domain' in your code.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Well, I overloaded operator<< to produce the output of a class that I
designed. But shouldn't the compiler deduct this from the type being
passed to operator<<???? Why is it the call ambiguous????

Does Domain perhaps accept a char* as a constructor?
Yes it does!!! The domain class can be created with a char* that I
pass (the name of a file). Why is this happening then?

Sep 26 '07 #7

P: n/a
"aaragon" <al**************@gmail.comwrote in message
news:11*********************@22g2000hsm.googlegrou ps.com...
On Sep 26, 3:14 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
>"aaragon" <alejandro.ara...@gmail.comwrote in message

news:11**********************@22g2000hsm.googlegr oups.com...
On Sep 26, 2:41 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
aaragon wrote:
Hello, does anyone have a clue about this error? and how to solve
it?
It seems to be trivial to me, but not for the compiler. I'm using
g++
4.2 on an Ubuntu Linux system:
// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...
main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char,
_Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*)
[with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1
>I don't see any "Domain.h" or types called 'Domain' in your code.
>V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Well, I overloaded operator<< to produce the output of a class that I
designed. But shouldn't the compiler deduct this from the type being
passed to operator<<???? Why is it the call ambiguous????

Does Domain perhaps accept a char* as a constructor?

Yes it does!!! The domain class can be created with a char* that I
pass (the name of a file). Why is this happening then?
I'm not actually positive, because I can't reproduce it in test, but what it
seems is that the compiler sees you are sending a char* to an ofstream. It
looks at sees that you have a Domain constructor that accepts a char* and
has an output to an ofstream. I wouldn't think that the compiler would pick
that, but it depends on how Domain is set up. Can you post the appropriate
Domain class? At least anything having to do with the constructor and any
operator<< overrides and such.
Sep 27 '07 #8

P: n/a
On Sep 26, 9:36 pm, aaragon <alejandro.ara...@gmail.comwrote:
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:
// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...
main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1
Apparently, you have defined function operator<<( ofstream&,
....), and Domain has a constructor which can be called with a
char const*. So the first argument of this function is an exact
match, and thus a better than the operator<<( ostream&, char
const*). The second argument, of course, is a better match for
the first function, so the call is ambiguous.

The obvious question is: why on earth would you define an
operator<< which takes an ofstream, rather than an ostream? If
you define the operator to take an ostream, then both functions
are equally good matches for the first argument, and the fact
that the char const* is a better match for the second means that
it will be chosen.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 27 '07 #9

P: n/a
aaragon <al**************@gmail.comwrote in
news:11*********************@22g2000hsm.googlegrou ps.com:
>>
Does Domain perhaps accept a char* as a constructor?

Yes it does!!! The domain class can be created with a char* that I
pass (the name of a file). Why is this happening then?

A literal string like "Hello" is actually of type char const [6] and
requires an implicit cast to become a char const * for operator<<.
Unless you have your domain class constructor marked as explicit, the compiler
sees that as an additional way to convert your literal string into something
that operator<< knows how to handle. In other words, both

fout << static_cast<char *>("Hello");

and

fout << static_cast<Domain>("Hello");

are viable choices and the compiler doesn't know which one you want. Of course,
you would never write like the above, but I was trying to represent it in a way
that would show that to the compiler, both are equally viable, though to your
eyes and mine, the first is the obvious choice. To tell the compiler that the
first is the obvious choice, you should mark the constructor for the Domain as explicit.

Interestingly enough VC8 doesn't see an ambiguity, though it should.

joe
Sep 27 '07 #10

P: n/a
Joe Greer <jg****@doubletake.comwrote in
news:Xn*********************************@194.177.9 6.78:
>
Interestingly enough VC8 doesn't see an ambiguity, though it should.
Ah, James Kanz reply explains why my quickly cobbled together test didn't
show the ambiguity in VC8. I overloaded for ostream instead of fostream
and had a better match. (You have to love a language which takes this kind
of analysis to figure out what's going on, don't you?) In any case, I think
that if you mark your constructor as explicit, you will solve your problem and
possibly prevent others like this.

joe
Sep 27 '07 #11

P: n/a
On Sep 27, 4:53 am, James Kanze <james.ka...@gmail.comwrote:
On Sep 26, 9:36 pm, aaragon <alejandro.ara...@gmail.comwrote:
Hello, does anyone have a clue about this error? and how to solve it?
It seems to be trivial to me, but not for the compiler. I'm using g++
4.2 on an Ubuntu Linux system:
// main()
...
std::ofstream fout;
fout.open("hello.out");
fout<<setfill('-')<<setw(20)<<"-"<<setfill(' ')<<endl;
fout<<"hello "; // this is line 139
...
main.cxx:89: instantiated from here
main.cxx:139: error: 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/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
ostream.tcc:735: note: candidate 1: std::basic_ostream<char, _Traits>&
std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with
_Traits = std::char_traits<char>]
Domain.h:507: note: candidate 2: o& operator<<(o&, const Domain&)
[with o = std::ofstream]
make: *** [main.o] Error 1

Apparently, you have defined function operator<<( ofstream&,
...), and Domain has a constructor which can be called with a
char const*. So the first argument of this function is an exact
match, and thus a better than the operator<<( ostream&, char
const*). The second argument, of course, is a better match for
the first function, so the call is ambiguous.

The obvious question is: why on earth would you define an
operator<< which takes an ofstream, rather than an ostream? If
you define the operator to take an ostream, then both functions
are equally good matches for the first argument, and the fact
that the char const* is a better match for the second means that
it will be chosen.

--
James Kanze (GABI Software) email:james.ka...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Well, I actually defined operator<< as a template function that could
take an ostream or a ofstream. Thus, I can output to screen using cout
and output to a file using an ofstream with the same code. I will
declare the constructor as explicit. Thank you guys for all your
answers! They're very appreciated.

Sep 27 '07 #12

P: n/a
On 2007-09-27 12:04:48 -0400, aaragon <al**************@gmail.comsaid:
>
Well, I actually defined operator<< as a template function that could
take an ostream or a ofstream. Thus, I can output to screen using cout
and output to a file using an ofstream with the same code. I will
declare the constructor as explicit. Thank you guys for all your
answers! They're very appreciated.
Making the constructor explicit treats the symptom, but not the
problem. To be able to write to an ofstream as well as to cout, write
an inserter that takes an ostream&. That's what all the standard
inserters do (well, actually, they're templates, and they take an
appropriate instantiation of basic_ostream).

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Sep 27 '07 #13

P: n/a
On Sep 27, 12:16 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2007-09-27 12:04:48 -0400, aaragon <alejandro.ara...@gmail.comsaid:
Well, I actually defined operator<< as a template function that could
take an ostream or a ofstream. Thus, I can output to screen using cout
and output to a file using an ofstream with the same code. I will
declare the constructor as explicit. Thank you guys for all your
answers! They're very appreciated.

Making the constructor explicit treats the symptom, but not the
problem. To be able to write to an ofstream as well as to cout, write
an inserter that takes an ostream&. That's what all the standard
inserters do (well, actually, they're templates, and they take an
appropriate instantiation of basic_ostream).

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)
Could you expand on the inserter subject? or give me a link where I
can read about it? Thank you.

Sep 28 '07 #14

P: n/a
On Sep 27, 2:27 pm, Joe Greer <jgr...@doubletake.comwrote:
Joe Greer <jgr...@doubletake.comwrote
innews:Xn*********************************@194.177 .96.78:
Interestingly enough VC8 doesn't see an ambiguity, though it should.
Ah, James Kanz reply explains why my quickly cobbled together
test didn't show the ambiguity in VC8. I overloaded for
ostream instead of fostream and had a better match. (You have
to love a language which takes this kind of analysis to figure
out what's going on, don't you?)
There are several places where you need this kind of analysis if
you really want to understand what's going on; function overload
resolution is one of them. On the other hand, in the case of
function overload resolution, it normally "does what you'd
expect", at least in well written code. In this case, the rule
is simple---overloaded << operators should *always* take an
std::ostream&, and not an std::ofstream&. Independant of the
overload ambiguities:
someFile << "label: " << objectOfMyType ;
will not work otherwise, since the << for char const* will
return an ostream&, and not an ofstream&.
In any case, I think that if you mark your constructor as
explicit, you will solve your problem and possibly prevent
others like this.
It's quite possible that it would be a good idea to mark the
constructor as explicit---IMHO, that should be the default, and
implicit conversions are often a source of ambiguities and other
problems. But in this case, there is an absolute rule: the <<
should *always* take an ostream& as its first argument, never a
class derived from ostream.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 28 '07 #15

P: n/a
On Sep 28, 5:32 am, aaragon <alejandro.ara...@gmail.comwrote:
On Sep 27, 12:16 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2007-09-27 12:04:48 -0400, aaragon <alejandro.ara...@gmail.comsaid:
Well, I actually defined operator<< as a template function that could
take an ostream or a ofstream. Thus, I can output to screen using cout
and output to a file using an ofstream with the same code. I will
declare the constructor as explicit. Thank you guys for all your
answers! They're very appreciated.
Making the constructor explicit treats the symptom, but not the
problem. To be able to write to an ofstream as well as to cout, write
an inserter that takes an ostream&. That's what all the standard
inserters do (well, actually, they're templates, and they take an
appropriate instantiation of basic_ostream).
Could you expand on the inserter subject? or give me a link
where I can read about it? Thank you.
There's not much to expand. As Pete said, an inserter (an
operator<<) should always take an instantiation of basic_ostream
as its first parameter (unless it is designed to insert into
streams unrelated to basic_ostream). Unless you really want to
be able to insert into any type of basic_ostream (a lot of work,
generally for nothing), just use std::ostream&.

All of the other output streams (ofstream, ostringstream, etc.)
and the bi-directional streams (iostream, fstream, stringstream)
derive from ostream, so an << taking an ostream will output
correctly to any of them. All of the standard << operators
return an ostream, so if you write something like:

out << "label: " << objectOfMyType ;

it will only work if objectOfMyType has an << defined that works
for ostream. The only time you write an operator<< which
doesn't take an ostream& as its first parameter (and return an
ostream&) is when you don't want it to work in cases like the
above; that would only be the case when the standard <<
operators are not appropriate for the stream. (I have an
oxdrstream, for example, where this is the case: it outputs data
in the binary xdr format, and not as text.)

A priori, the iostream's chapter in Josuttis covers the issue.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 28 '07 #16

This discussion thread is closed

Replies have been disabled for this discussion.