gpt4 book ai didi

c++ - "ambiguous overload for ' operator[] '"如果存在到 int 的转换运算符

转载 作者:IT老高 更新时间:2023-10-28 22:35:02 24 4
gpt4 key购买 nike

我正在尝试为一个类实现类似 vector 和类似 map 的 [] 运算符。但我从我的编译器(g++ 和 clang++)收到错误消息。发现它们只有在类也有转换为整数类型的运算符时才会发生。

现在我有两个问题。首先是我不知道为什么编译器在类有的时候不能区分 [](const std::string&) 和将运算符转换为整数。第二个......我需要转换和索引运算符。如何解决?

作品:

#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的操作符,所以编译器不知道是否:

  1. 从字符串文字构造一个 std::string 并调用接受 std::string;
  2. 的重载
  3. 将您的 Foo 对象转换为 uint32_t 并将其用作字符串文字的索引。

虽然选项 2 可能听起来令人困惑,但请考虑以下表达式在 C++ 中是合法的:

1["foo"];

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

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。要解决歧义,您可以使转换运算符 explicit(在 C++11 中):

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

或者您可以保留该转换运算符,并显式构造 std::string 对象:

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

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

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

另外请注意,您的函数具有非 void 返回类型,但目前缺少 return 语句。这会在您的程序中注入(inject)未定义行为

关于c++ - "ambiguous overload for ' operator[] '"如果存在到 int 的转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15850840/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com