gpt4 book ai didi

c++ - 重载 operator[] 的使用不明确

转载 作者:行者123 更新时间:2023-12-05 04:23:03 34 4
gpt4 key购买 nike

简化代码如下:

#include <string>
#include <string_view>

struct object{
operator std::string(){return "";}
}

struct foo{
foo operator[](std::string_view s){
return foo{};
}

template <typename T>
operator T(){
return object{};
}
};

int main(){
foo f;
std::string s = f["a"];
}

clang 报错:

error: use of overloaded oeprator '[]' is ambiguous (with oeprand types 'foo' and 'const char*')
note: candidate function foo operator[](std::string_view s)
note: built-in candidate operator[](long, const char*)
note: built-in candidate operator[](long, const volatile char*)

但是 gcc 成功编译了上面的代码。

clang版本是12.0.1,gcc是7.5.0

我很困惑,哪个编译器是正确的?

最佳答案

template <typename T>
operator T(){
return object{};
}

我认为这里的 clang 是正确的,因为这个片段使 foo 类可以转换为任何类型,并且 viable template functions are supposed to be instantiated在重载决议发挥作用之前:

Before overload resolution begins, the functions selected by namelookup and template argument deduction are combined to form the set ofcandidate functions

如您所见,重载与以下参数作斗争:(long, const char*),因此它必须是类似于此 3["a"]< 的表达式 根据 cppreference 完全合法:

expr1 [ expr2 ]

For the built-in operator, one of the expressions (either expr1 orexpr2) must be a glvalue of type “array of T” or a prvalue of type“pointer to T”, while the other expression (expr2 or expr1,respectively) must be a prvalue of unscoped enumeration or integraltype. The result of this expression has the type T


然而,它也提供了如何区分内置下标和自定义重载的线索:

expr1 [ { expr, ... } ]

The form with brace-enclosed list inside the square brackets is only used to call an overloaded operator[].

所以你说的例子如果这样写应该不错了:

int main(){
foo f;
std::string s = f[{"a"}];
return 0;
}

或者将下标显式转换为字符串,这样编译器就不会将它与数组的内置运算符混淆:

int main(){
using namespace std::string_literals;

foo f;
std::string s = f["a"s];
return 0;
}

关于c++ - 重载 operator[] 的使用不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73796007/

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