我有以下类(class):
class DictionaryRef {
public:
operator bool() const;
std::string const& operator[](std::string const& name) const;
// ...
};
然后我尝试使用它:
DictionaryRef ref = ...;
ref["asdf"]; // error
输出提示两个重载,但只列出一个:
1>...: error C2666: 'DictionaryRef::operator []' : 2 overloads have similar conversions
1> ...: could be 'const std::string &DictionaryRef::operator [](const std::string &) const'
1> while trying to match the argument list '(DictionaryRef, const char *)'
但是,将鼠标悬停在带下划线的部分上,弹出窗口告诉我第二个选项是built-in operator integer[pointer-to-object]
。显然它考虑将对象转换为 bool,然后使用神秘的运算符 int[char const*]
。我以前从未听说过这个运算符,但显然 3["asdf"]
与 "asdf"[3]
相同?有没有人曾经使用过这种语法,或者它是 C 的一些非常古老的残余?此外,是否需要两次转换才能到达那里 - 首先是从 DictionaryRef
到 bool
,然后是从 bool
到 int
?
最佳答案
这是违反直觉的,但根据规范,下标是一个交换运算符。
第 5.2.1 段下标说:
后缀表达式后跟方括号中的表达式是后缀表达式。表达方式之一 应具有“T 数组”或“指向 T 的指针”类型,另一个应具有无作用域枚举 或积分型。结果是类型“T”。类型“T”应是完全定义的对象类型。 64 表达式 E1[E2] 等同于(根据定义)*((E1)+(E2))。
这意味着当x
是一个数组,i
是一个整数时,x[i]
是 *((x)+(i))
也是 i[x]
。
这就是运算符 int[char const *]
的原因:它与运算符 (char const *)[int]
的操作相同。
作为引用,C 支持相同的特性:在 C 语言规范中,关于数组下标的 6.5.2.1 段落也说:
其中一个表达式的类型应为“指向完整对象类型的指针”,另一个 表达式应为整数类型,结果的类型为“类型”。
后缀表达式后跟方括号 [] 中的表达式是带下标的 指定数组对象的元素。下标运算符[]的定义 是 E1[E2] 等同于 (*((E1)+(E2)))。
关于c++ - 2 个重载具有相似的转换 - 内置运算符 integer[pointer-to-object],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31269522/