问题
Consider the following code:
#include <stdio.h>
#include <stdint.h>
class test_class
{
public:
test_class() {}
~test_class() {}
const int32_t operator[](uint32_t index) const
{
return (int32_t)index;
}
operator const char *() const
{
return "Hello World";
}
};
int main(void)
{
test_class tmp;
printf("%d\n", tmp[3]);
return 0;
}
When I use command clang++ -arch i386 test.cc
to build those codes, it yields the following on clang++ (Apple LLVM version 9.1.0 (clang-902.0.39.1)):
test.cc:24:21: error: use of overloaded operator '[]' is ambiguous (with operand types 'test_class' and 'int')
printf("%d\n", tmp[3]);
~~~^~
test.cc:10:17: note: candidate function
const int32_t operator[](uint32_t index) const
^
test.cc:24:21: note: built-in candidate operator[](const char *, int)
printf("%d\n", tmp[3]);
^
test.cc:24:21: note: built-in candidate operator[](const volatile char *, int)
But there is no error if I just use command clang++ test.cc
It seems that overloading operator '[]' on i386 is different from on x86_64 and I want to know what the exactly distinction is.
回答1:
There are two possible interpretations of tmp[3]
: the "obvious" one, calling test_class::operator[](int32_t)
, and the less obvious one, calling test_class::operator const char*()
to convert the object to a const char*
, and applying the index to that pointer.
To decide which of the overloads to use, the compiler looks at the conversions involved. There are two arguments for each overload: tmp
and 3
. For the first overload, tmp
needs no conversion, but 3
has to be converted from int
to int32_t
. For the second overload, tmp
needs to be converted to const char*
, and 3
does not have to be converted.
To choose the proper overload, the compiler has to look at the conversion set for each argument. For the first argument, tmp
, the first overload requires no conversion, and the second requires an integral conversion. So the first overload wins here. For the second argument, the first overload requires a user-defined conversion and the second requires no conversion. So the first conversion wins.
In short: the first overload wins on the first argument, and the second overload wins on the second argument. So the call is ambiguous.
You could add an overloaded operator[](int)
, which would resolve this particular complaint, but it would be an error with a compiler where int32_t
is a synonym for int
.
Your best bet is probably to get rid of operator[](int32_t)
and replace it with operator[](int)
.
This is why you have to think carefully about fixed-size types: you can get conversions that you aren't expecting.
来源:https://stackoverflow.com/questions/49607565/error-use-of-overloaded-operator-is-ambiguous-while-building-for-i386