Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving ambiguous overload of operator[]

I have this class:

class MyClass {

    public:

        int operator[](const std::string&);
        const std::string& operator[](const int&) const;

    ...
};

It works greatly, however, if i call the second operator w/ const literal 0:

MyClass myclass;
std::cout << myclass[0] << std::endl;

I got this error:

In function 'int main()':
ambiguous overload for 'operator[]' in 'myclass[0]'
note: candidates are:
note: const int MyClass::operator[](const string&)|
note: const string& MyClass::operator[](const int&) const

I guess i understand what's the situation (0 can be either a string or int?), but my question is: is there any way to resolve this and keep the operator overloading?

like image 475
WonderCsabo Avatar asked Dec 20 '12 19:12

WonderCsabo


1 Answers

Calling MyClass::operator[](const std::string&) involves converting:

myclass from MyClass& to MyClass&: perfect match

0 from int to const char* to std::string: user-defined conversion

Calling MyClass::operator[](const int&) const involves converting:

myclass from MyClass& to const MyClass&: const qualification

0 from int to int: perfect match

In a situation like this, when one overload is "better" for argument X but a different overload is "better" for argument Y, neither overload can be considered the best overload, and the compiler must complain (assuming no third overload beats both).

Is it possible to change the two overloads to be both const or both non-const? If not, you could add a third overload to handle this sort of situation:

const std::string& operator[](int n) {
    return static_cast<const MyClass&>(*this)[n];
}
like image 183
aschepler Avatar answered Sep 22 '22 22:09

aschepler