“对于操作符[]'的”不确定重载“如果转换操作符为int存在 [英] "ambiguous overload for 'operator[]'" if conversion operator to int exist

查看:190
本文介绍了“对于操作符[]'的”不确定重载“如果转换操作符为int存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现一个类的矢量和像[]运算符的地图。但我从我的编译器(g ++和clang ++)收到错误消息。发现它们只发生在类也有转换运算符到整数类型。

I'm trying to implement the vector like and the map like [] operator for a class. But I get error messages from my compilers (g++ and clang++). Found out that they only occurs if the class has also conversion operators to integer types.

现在我有两个问题。第一个是我不知道为什么编译器不能区分[](const std :: string&)和类有转换运算符到int。
第二个...我需要转换和索引操作符。

Now I have two problems. The first is that I don't know why the compiler can't distinguish between [](const std::string&) and when the class has conversion operators to ints. The second... I need the conversion and the index operator. Does anyone know how to fix that?

工作原理:

#include <stdint.h>
#include <string>

struct Foo
{
    Foo& operator[](const std::string &foo) {}
    Foo& operator[](size_t index) {}
};

int main()
{
    Foo f;
    f["foo"];
    f[2];
}

无效:

#include <stdint.h>
#include <string>

struct Foo
{
    operator uint32_t() {}
    Foo& operator[](const std::string &foo) {}
    Foo& operator[](size_t index) {}
};

int main()
{
    Foo f;
    f["foo"];
    f[2];
}

编译器错误:

main.cpp: In function 'int main()':
main.cpp:14:9: error: ambiguous overload for 'operator[]' in 'f["foo"]'
main.cpp:14:9: note: candidates are:
main.cpp:14:9: note: operator[](long int, const char*) <built-in>
main.cpp:7:7: note: Foo& Foo::operator[](const string&)
main.cpp:8:7: note: Foo& Foo::operator[](size_t) <near match>
main.cpp:8:7: note:   no known conversion for argument 1 from 'const char [4]' to 'size_t {aka long unsigned int}'


推荐答案

问题是你的类有一个转换操作符 uint32_t ,因此编译器不知道是否:

The problem is that your class has a conversion operator to uint32_t, so the compiler does not know whether to:


  1. 构造一个 std :: string 从字符串文字中调用你的重载接受 std :: string ;

  2. < Foo 对象转换为 uint32_t ,并将其用作字符串文字的索引。
  1. Construct a std::string from the string literal and invoke your overload accepting an std::string;
  2. Convert your Foo object into an uint32_t and use it as an index into the string literal.

虽然选项2可能听起来很混乱,但考虑下面的表达式在C ++中是合法的:

While option 2 may sound confusing, consider that the following expression is legal in C++:

1["foo"];

这是因为如何定义内置下标运算符。根据C ++ 11标准的第8.3.4 / 6段:

This is because of how the built-in subscript operator is defined. Per Paragraph 8.3.4/6 of the C++11 Standard:


),下标运算符[]被解释为这样的
a方式, E1 [E2] 等同于 *((E1)+ E2))。由于适用于+的转换规则,如果 E1
数组,而 E2 那么 E1 [E2] 是指 E2 E1 。因此,尽管其出现不对称的
下标是可交换操作

Except where it has been declared for a class (13.5.5), the subscript operator [] is interpreted in such a way that E1[E2] is identical to *((E1)+(E2)). Because of the conversion rules that apply to +, if E1 is an array and E2 an integer, then E1[E2] refers to the E2-th member of E1. Therefore, despite its asymmetric appearance, subscripting is a commutative operation.

上面表达式 1 [foo] 等效于foo[1] ,其计算结果为 o 。要解决歧义,您可以使转换运算符显式(在C ++ 11中):

Therefore, the above expression 1["foo"] is equivalent to "foo"[1], which evaluates to o. To resolve the ambiguity, you can either make the conversion operator explicit (in C++11):

struct Foo
{
    explicit operator uint32_t() { /* ... */ }
//  ^^^^^^^^
};

或者你可以保留这个转换操作符,并构造 std :: string 显式:

Or you can leave that conversion operator as it is, and construct the std::string object explicitly:

    f[std::string("foo")];
//    ^^^^^^^^^^^^     ^

您可以添加一个接受 const char * 的下标运算符的进一步重载,这将是比上述任何一个更好的匹配(因为它不需要用户定义的转换):

Alternatively, you can add a further overload of the subscript operator that accepts a const char*, which would be a better match than any of the above (since it requires no user-defined conversion):

struct Foo
{
    operator uint32_t() { /* ... */ }
    Foo& operator[](const std::string &foo) { /* ... */ }
    Foo& operator[](size_t index) { /* ... */ }
    Foo& operator[](const char* foo) { /* ... */ }
    //              ^^^^^^^^^^^
};

还要注意,你的函数有一个非void返回类型, $ c> return 语句。此操作会在您的程序中插入未定义行为

Also notice, that your functions have a non-void return type, but currently miss a return statement. This injects Undefined Behavior in your program.

这篇关于“对于操作符[]'的”不确定重载“如果转换操作符为int存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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