ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with _Traits = std::char_traits<char>]
std::fstream& operator<<(std::fstream&, const Fotografia&)

What I understood so far is that there's ambiguosity between the overloaded function I just created and the standard fstream << .
Now, what I do not understand is why, because my overloaded function should work just for the class "Fotografia" (which was created by me), while I am trying to write a char * .

I thought I could solve this problem by calling the fstream operator with the "::" scope but I am not sure.

Shouldn't the fstream passed into operator<< be opened and closed by the caller? as it is passing it in and out of the function is kind of pointless. About your problem: Do you have any implicit conversions between char* and Fotografia (operator char* or Fotografia(const char*))?
–
GrizzlyJan 30 '13 at 18:09

2 Answers
2

Also, instead of limiting the code to inserting in an fstream, you could insert into an arbitrary basic_ostream. That would still work for an fstream, and would give you more flexibility to use other forms of output streams. That would also eliminate the error.

I'm not sure I'm following you, Pete. Both fstream and ostream are ultimately basic_ostream<char>. He could try using basic_ostream<unsigned char>, but I'm not sure the behavior is defined if he does. The standard doesn't specify any semantics for it, and I suspect that something like std::basic_ofstream<unsigned char> will not work in most implementations. (Personally, I still think making the iostreams templates, rather than just supplying two separate classes, was a mistake. Sort of violates the KISS principle, since you can only use two instantiations anyway.)
–
James KanzeJan 30 '13 at 18:29

@JamesKanze: Wouldn't having different classes for char and wchar_t violate DRY? Especialy when it comes to supporting custom streamout for both cases. Always writing a completely generic template and using sfinae to enable it only for stream classes is a bit cumbersome afterall.
–
GrizzlyJan 30 '13 at 18:34

@JamesKanze - heh, I didn't read the question carefully enough. Still, I stand by the conclusions, even if the logic is flawed. <g>
–
Pete BeckerJan 30 '13 at 18:57

@Grizzly I'm not sure what DRY means, but... One of the problems with the template solution is that it forces both classes to have the same semantics. When they really shouldn't.
–
James KanzeJan 30 '13 at 19:25

I made an edit to my first post and put the code for my header and constructor, I don't have the "operator char*" anywhere, could you please point out what I should mark explicit? Thanks a lot for your patience and kind help! ---Edit: Got it! Thanks for your help!!! ---
–
AndrewJan 30 '13 at 19:42

It makes no sense to overload operator<< for std::fstream.
First, because experienced C++ programmers hardly every use
std::fstream; they use std::ofstream or std::ifstream.
And second, because once you've used a <<, the return value is
a std::ostream anyway, so the operator<< for ofstream
would never be called.

Of course, your implementation of the operator also violates all
of the rules. You don't open or close a file in the operator;
the operator is for formatting the data. If you want to
support two different formats, the usual way would be to define
a manipulator to choose between them, and let the client decide.
(See std::ios_base::xalloc() and company for where to put the
additional state.)

Good point, I'll try and use accordingly ofstream and ifstream instead of fstream. Also, I am going to let the user open and close the file, while the operator manipulates the data. Thanks for your help!
–
AndrewJan 30 '13 at 19:41