Consider the following class:
class Foo
{
public:
void operator [] (const std::string& s) { }
void operator [] (std::size_t idx) { }
};
Here, given an instance of Foo f
, the expression f[0]
is not ambiguous, because the compiler chooses the second overload. Likewise, the expression f["abc"]
is not ambiguous, because the compiler chooses the first overload (since a const char*
is convertible to an std::string
).
So, why is it then, that if we have two Base classes, each with a different overload, that there is suddenly ambiguity?
Suppose we have:
class Base1
{
public:
void operator [] (const std::string& s) { }
};
class Base2
{
public:
void operator [] (std::size_t idx) { }
};
class Derived : public Base1, public Base2
{ };
Now, if we say:
Derived d;
d[0];
The compiler complains:
error: request for member ‘operator[]’ is ambiguous
d[0];
^
note: candidates are: void Base2::operator[](std::size_t)
void operator [] (std::size_t idx) { }
^
note: void Base1::operator[](const string&)
void operator [] (const std::string& s) { }
Why does the fact that both operator overloads are now in Base classes cause any ambiguity? And is there some way to resolve this?
EDIT: Could this be a compiler bug (I am using GCC 4.8.1)