Possible Duplicate:
Why do multiple-inherited functions with same name but different signatures not get treated as overloaded functions?
This fails to compile in the indicated place with g++ 4.6.1:
enum Ea { Ea0 };
enum Eb { Eb0 };
struct Sa { void operator()(Ea) {} };
struct Sb { void operator()(Eb) {} };
struct Sbroken : Sa, Sb {};
struct Sworks {
void operator()(Ea) {}
void operator()(Eb) {}
};
int main() {
Sworks()(Ea0);
Sbroken()(Ea0); // g++ can't disambiguate Ea vs. Eb
}
Clang 2.8 does compile this code, which makes me uncertain if the code is really valid C++ or not. I was about to conclude optimistically that clang was right and g++ was wrong, but then I made a small change which made clang have a similar error:
enum Ea { Ea0 };
enum Eb { Eb0 };
struct Sa { void f(Ea) {} };
struct Sb { void f(Eb) {} };
struct Sbroken : Sa, Sb {};
struct Sworks {
void f(Ea) {}
void f(Eb) {}
};
int main() {
Sworks().f(Ea0);
Sbroken().f(Ea0); // both clang and g++ say this is ambiguous
}
The only change I made there was to use a named function f
rather than operator()
. I don't see why this should even matter, but it does: this version does not compile with g++ nor with clang.
I think it has something to do with hiding the function(s) in the base classes, and the GCC's error message doesn't seem to help much, even if you use struct
instead of enum
: In fact, the error message is misleading, because now Ea
and Eb
are two different classes, with no implicit conversion from Ea
to Eb
, the ambiguity shouldn't arise, but GCC seems to disagree with me : http://ideone.com/cvzLW (see the modification also).
Anyway, if you bring the functions in the class scope, explicitly by writing using
as:
struct Sbroken : Sa, Sb
{
using Sa::operator();
using Sb::operator();
};
then it works : http://ideone.com/LBZgC
Same with other example as well:
struct Sbroken : Sa, Sb
{
using Sa::f;
using Sb::f;
};
Code : http://ideone.com/3hojd