help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: error: ambiguous overload for 'operator <<' in ...


From: Paul Pluzhnikov
Subject: Re: error: ambiguous overload for 'operator <<' in ...
Date: Fri, 27 Oct 2006 07:01:36 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) XEmacs/21.4 (Jumbo Shrimp, linux)

glen <stark@ife.ee.ethz.ch> writes:

>       - I provided an example.  It wasn't minimal enough for you?

The problem isn't that the example is not minimal.

The problem is that the example is incomplete. I.e. I can't cut/paste
that example and observe the same error.

It is simple enough to add missing '#include's, to make it complete,
but why are you making *me* work? You should have done that (minimal)
work yourself.

> Let me try again

There is no reason to try again.
You have already been given *the* answer, but you didn't understand it :-(

The answer (from Ulrich Eckhardt) is:

>> Well, anyways, your operator's signature matches _EVERYTHING_, including a
>> character literal.

Let me try to explain that answer for you.

>   template<typename C>
>   std::ostream& operator<< (std::ostream& op, const C& cpi )

The problem is that this template function will match *anything*.
It will be a match for:

    std::cout << 1;           // C == "const int"
    std::cout << 'a';         // C == "char"
    std::cout << "abc";       // C == "const char[4]"
    .... etc ...

So it makes all the *standard* "std::operator<<(...)" ambigous,
and compiler tells you exactly that -- that it's "standard"

  std::ostream::operator<<(long int)
  std::ostream::operator<<(long unsigned int)
  std::ostream::operator<<(bool)
  std::ostream::operator<<(short int)
  ... etc ...

have been ambigously overloaded (by you), and compiler now doesn't
know which of these possible overloads it's supposed to call.

I don't see any way to overload ostream::operator<<() such that it 
will output arbitrary container, but will not ambiguate standard
overloads. 

I think you'll just have to rewrite offending code. Instead of

   cout << myRange;

you'll have to do:

   print(cout, myRange.begin(), myRange.end()); // [1]
or
   myRange.print(cout); // [2]

For [1], it is trivial to define 

  // warning: untested
  template <typename C> std::ostream& 
  print(std::ostream&, 
        typename C::const_iterator first, 
        typename C::const_iterator last) { ... }

For [2], just define appropriate "print" method in the Range class.

Cheers,
-- 
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]