Reputation: 71
When I try to compile (with gcc 4.3.4) this code snippet:
enum SimpleEnum {
ONEVALUE
};
void myFunc(int a) {
}
void myFunc(char ch) {
}
struct MyClass {
operator int() const { return 0; };
operator SimpleEnum() const { return ONEVALUE; };
};
int main(int argc, char* argv[]) {
myFunc(MyClass());
}
I get this error:
test.cc: In function "int main(int, char**)":
test.cc:17: error: call of overloaded "myFunc(MyClass)" is ambiguous
test.cc:5: note: candidates are: void myFunc(int)
test.cc:8: note: void myFunc(char)
I think I (almost) understand what the problem is, i.e. (simplifying it a lot) even if I speak about "char" and "enum", they all are integers and then the overloading is ambiguous.
Anyway, the thing I don't really understand is that if I remove the second overloading of myFunc OR one of the conversion operators of MyClass, I have no compilation errors.
Since I'm going to change A LOT of old code because of this problem (I'm porting code from an old version of HP-UX aCC to g++ 4.3.4 under Linux), I would like to understand better the whole thing in order to choose the best way to modify the code.
Thank you in advance for any help.
Upvotes: 7
Views: 2192
Reputation: 6982
enum
s are types in C++, unlike C.
There are implicit conversions for both enum
-> char
and enum
-> int
. The compiler just doesn't know which one to choose.
EDIT: After trying with different tests:
MyClass
-> int
is removed, code compiles.int
and so it is the one favored by the compiler over the one to char
. Test here.void myFunc(int)
is removed compilation fails.MyClass
to char
and finds that, not having a user defined conversion operator char()
, both user defined int()
and SimpleEnum()
may be used. Test here.char()
conversion operator for MyClass
compilation fails with the same error as if not.So the conclusion I come up with here is that in your originally posted code compiler has to decide which of the two overloaded versions of myFunc
should be called.
Since both conversions are possible:
MyClass
to int
via user defined conversion operator.MyClass
to int
via user defined conversion (MyClass
to SimpleEnum
) + implicit conversion (SimpleEnum
to char
)compiler knows not which one to use.
Upvotes: 4
Reputation: 477100
The conversion from MyClass
is ambiguous, as there is one conversion to int
and one to the enum, which is itself implicitly convertible to int
, and both are equally good conversions. You can just make the call explicit, though, by specifying which conversion you want:
myfunc(int(MyClass()));
Alternatively, you might like to rethink why you have a function that has separate overloads for int
and char
, perhaps that could be redesigned as well.
Upvotes: 4
Reputation: 81349
I would have expected that the int overload is called. Tried a few compilers and got different results. If you are going to remove anything, remove the user conversion operator to int
, since enums have a standard conversion to ints.
Upvotes: 1