Error: use of overloaded operator '[]' is ambiguous while building for i386

a 夏天 提交于 2021-02-09 08:29:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!