Search code examples
c++overloadingoperator-keywordambiguity

How can I prevent integer ambiguity when overloading operators in C++


Given the following code:

#include <string>
#include <sstream>

class SomeClass {
public:
    SomeClass& operator<<(long value) { return *this; }

    SomeClass& operator<<(unsigned long value) { return *this; }

    SomeClass& operator<<(float value) { return *this; }

    SomeClass& operator<<(double value) { return *this; }

    SomeClass& operator<<(long double value) { return *this; }

    SomeClass& operator<<(bool value);
    { return *this; }

    SomeClass& operator<<(const void* value);
    { return *this; }

    SomeClass& operator<<(::std::string aString) { return *this; }
};

int main() {
    SomeClass aClass;
    std::ostringstream aStream;

    aClass << 2;
    aClass << "Hello World";
    aClass << '\0';
    aClass << -2;

    aStream << 2;
    aStream << "Hello World";
    aStream << '\0';
    aStream << -2;

    return 0;
}

Why is basic_ostream able to overload << with so many integer types with no problem? Yet, the compiler is giving me ambiguous overload errors for SomeClass's << operators?

ex:

../OverloadTest.cpp:65: error: ambiguous overload for ‘operator<<’ in ‘aClass << 2’
../OverloadTest.cpp:14: note: candidates are: SomeClass& SomeClass::operator<<(long int)   
../OverloadTest.cpp:19: note:                 SomeClass& SomeClass::operator<<(long unsigned int)
../OverloadTest.cpp:24: note:                 SomeClass& SomeClass::operator<<(float)    
../OverloadTest.cpp:29: note:                 SomeClass& SomeClass::operator<<(double)    
../OverloadTest.cpp:35: note:                 SomeClass& SomeClass::operator<<(long double)    
../OverloadTest.cpp:40: note:                 SomeClass& SomeClass::operator<<(bool)    
../OverloadTest.cpp:46: note:                 SomeClass& SomeClass::operator<<(const void*)     
../OverloadTest.cpp:51: note:                 SomeClass& SomeClass::operator<<(std::string) 

Solution

  • You need to add overload at least for int (and for completing the code for unsigned int too).

    SomeClass& operator<<(int value) { return *this; }
    
    SomeClass& operator<<(unsigned int value) { return *this; }
    

    When you call: aClass << 2;

    Literal 2 is of type int, there not overload that fit exactly, the compiler need to convert the number, in the conversion is where the ambiguity appear. What is better for 2, long or unsigned long or float or double or long double or even bool, the compiler don't know.