错误:为i386构建时,使用重载的运算符'[]'模棱两可 [英] Error: use of overloaded operator '[]' is ambiguous while building for i386

查看:111
本文介绍了错误:为i386构建时,使用重载的运算符'[]'模棱两可的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

  #include< stdio.h>#include< stdint.h>类test_class{上市:test_class(){}〜test_class(){}const int32_t运算符[](uint32_t索引)const{返回(int32_t)索引;}运算符const char *()const{返回"Hello World";}};int main(无效){test_class tmp;printf(%d \ n",tmp [3]);返回0;} 

当我使用命令 clang ++ -arch i386 test.cc 生成这些代码时,在clang ++(Apple LLVM版本9.1.0(clang-902.0.39.1))上会产生以下内容:

  test.cc:24:21:错误:使用重载运算符'[]'不明确(操作数类型为'test_class'和'int')printf(%d \ n",tmp [3]);~~~ ^〜test.cc:10:17:注意:候选函数const int32_t运算符[](uint32_t索引)const^test.cc:24:21:注意:内置的候选运算符[](const char *,int)printf(%d \ n",tmp [3]);^test.cc:24:21:注意:内置的候选运算符[](const volatile char *,int) 

但是,如果我只使用命令 clang ++ test.cc

,就没有错误.

i386上的重载运算符'[]'似乎与x86_64上的重载运算符不同,我想知道确切的区别是什么.

解决方案

tmp [3] 有两种可能的解释:明显"的一种,调用 test_class :: operator [](int32_t),以及不太明显的一个,调用 test_class :: operator const char *()将对象转换为 const char * ,然后将索引应用于该指针.

要决定使用哪种重载,编译器会查看涉及的转换.每种重载都有两个参数: tmp 3 .对于第一次重载, tmp 不需要转换,但是 3 必须从 int 转换为 int32_t .对于第二次重载,需要将 tmp 转换为 const char * ,而不必转换 3 .

要选择适当的重载,编译器必须查看每个参数的转换集.对于第一个参数 tmp ,第一个重载不需要转换,而第二个重载则需要整数转换.因此,第一个过载在这里胜出.对于第二个参数,第一个重载需要用户定义的转换,第二个重载不需要转换.因此,第一个转换获胜.

简而言之:第一个重载在第一个参数上获胜,第二个重载在第二个参数上获胜.因此通话不明确.

您可以添加一个重载的 operator [](int),它可以解决此特定的投诉,但是对于其中 int32_t 是同义词的编译器,这将是一个错误.表示 int .

您最好的选择可能是摆脱 operator [](int32_t)并将其替换为 operator [](int).

这就是为什么您必须仔细考虑固定大小类型的原因:您可以获得意料之外的转换.

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.

解决方案

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.

这篇关于错误:为i386构建时,使用重载的运算符'[]'模棱两可的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆