Thread: operator << ambiguity

  1. #1
    Unregistered
    Guest

    Unhappy operator << ambiguity

    Hello, I hope someone can help me here, its probably a simple problem but I am going crazy trying to work out why the code below gives a compiler error as follows:

    c:\windows\desktop\src\day19\spunk.cpp(112) : error C2593: 'operator <<' is ambiguous
    c:\windows\desktop\src\day19\spunk.cpp(134) : see reference to function template instantiation 'class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> >
    &,const class Array<class Animal> &)' being compiled
    Error executing cl.exe.


    If you want to print an array of integers no problem! but if you try to use it with Animals you get the error.
    My brain hurts too much to work it out now. Even a clue would be nice.



    [code]

    #include <iostream>
    using namespace std;

    const int DefaultSize = 3;

    // A trivial class for adding to arrays
    class Animal
    {
    public:
    // constructors
    Animal(int);
    Animal();
    ~Animal();

    // accessors
    int GetWeight() const { return itsWeight; }
    void SetWeight(int theWeight) { itsWeight = theWeight; }

    // friend operators
    friend ostream& operator<< (ostream&, const Animal&);

    private:
    int itsWeight;
    };

    // extraction operator for printing animals
    ostream& operator<<
    (ostream& theStream, const Animal& theAnimal)
    {
    theStream << theAnimal.GetWeight();
    return theStream;
    }

    Animal::Animal(int weight):
    itsWeight(weight)
    {
    cout << "animal(int) ";
    }

    Animal::Animal():
    itsWeight(0)
    {
    cout << "animal() ";
    }

    Animal::~Animal()
    {
    cout << "Destroyed an animal...";
    }

    template <class T> // declare the template and the parameter
    class Array // the class being parameterized
    {
    public:
    Array(int itsSize = DefaultSize);
    Array(const Array &rhs);
    ~Array() { delete [] pType; }

    // operators
    Array& operator=(const Array&);
    T& operator[](int offSet) { return pType[offSet]; }
    const T& operator[](int offSet) const
    { return pType[offSet]; }

    // accessors
    int GetSize() const { return itsSize; }

    // friend function
    friend ostream& operator<< (ostream&, const Array<T>&);

    private:
    T *pType;
    int itsSize;
    };

    template <class T>
    Array<T>::Array(int size = DefaultSize):
    itsSize(size)
    {
    pType = new T[size];
    for (int i = 0; i<size; i++)
    pType[i] = (T)0;
    }

    template <class T>
    Array<T>& Array<T>:perator=(const Array &rhs)
    {
    if (this == &rhs)
    return *this;
    delete [] pType;
    itsSize = rhs.GetSize();
    pType = new T[itsSize];
    for (int i = 0; i<itsSize; i++)
    pType[i] = rhs[i];
    return *this;
    }

    template <class T>
    Array<T>::Array(const Array &rhs)
    {
    itsSize = rhs.GetSize();
    pType = new T[itsSize];
    for (int i = 0; i<itsSize; i++)
    pType[i] = rhs[i];
    }


    template <class T>
    ostream& operator<< (ostream& output, const Array<T>& theArray)
    {
    for (int i = 0; i<theArray.GetSize(); i++)
    output << "[" << i << "] " << theArray[i] << endl;
    return output;
    }


    Array<Animal>::Array(int AnimalArraySize):
    itsSize(AnimalArraySize)
    {
    pType = new Animal[AnimalArraySize];
    }


    void IntFillFunction(Array<int>& theArray);
    void AnimalFillFunction(Array<Animal>& theArray);

    int main()
    {
    Array<int> intArray;
    Array<Animal> animalArray;
    IntFillFunction(intArray);
    AnimalFillFunction(animalArray);
    cout << "intArray...\n" << intArray;
    cout << "\nanimalArray...\n" << animalArray << endl;
    return 0;
    }

    void IntFillFunction(Array<int>& theArray)
    {
    bool Stop = false;
    int offset, value;
    while (!Stop)
    {
    cout << "Enter an offset (0-2) and a value. ";
    cout << "(-1 to stop): " ;
    cin >> offset >> value;
    if (offset < 0)
    break;
    if (offset > 2)
    {
    cout << "***Please use values between 0 and 2.***\n";
    continue;
    }
    theArray[offset] = value;
    }
    }


    void AnimalFillFunction(Array<Animal>& theArray)
    {
    Animal * pAnimal;
    for (int i = 0; i<theArray.GetSize(); i++)
    {
    pAnimal = new Animal(i*10);
    theArray[i] = *pAnimal;
    delete pAnimal;
    }
    }

    [\code]

  2. #2
    Registered User
    Join Date
    Aug 2001
    Posts
    52
    Ok, here's your clue complements of the MSDN Library:

    Compiler Error C2593
    'operator identifier' is ambiguous

    More than one possible operator was defined for the specified overloaded operator.

    An explicit cast of one or more of the actual parameters can resolve the ambiguity.

    The following is an example of this error:
    Code:
    struct A {};
    struct B : A {};
    struct X {};
    struct D : B, X {};
    void operator+( X, X );
    void operator+( A, B );
    D d;
    void main()
    {
       d +  d;         // error, D has an A, B, and X 
       (X)d + (X)d;    // OK, uses operator+( X, X )
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Ambiguity issue
    By George2 in forum C++ Programming
    Replies: 21
    Last Post: 02-11-2008, 12:52 AM
  2. Ambiguity error with double as parameter type
    By tejasvsrinivasa in forum C++ Programming
    Replies: 2
    Last Post: 11-11-2007, 04:17 PM
  3. Inheritence ambiguity
    By bennyandthejets in forum C++ Programming
    Replies: 3
    Last Post: 12-04-2003, 07:02 PM
  4. How to avoid template ambiguity
    By Shadow12345 in forum C++ Programming
    Replies: 2
    Last Post: 11-09-2002, 12:34 PM
  5. Multiple Inheritance Ambiguity
    By FillYourBrain in forum C++ Programming
    Replies: 21
    Last Post: 08-23-2002, 10:31 AM