我有以下课程:
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
?
答案 0 :(得分:4)
这是反直觉的,但根据规范,下标是一个可交换的运算符。
第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段也说:
其中一个表达式的类型''指向完整的对象类型'',另一个 expression应具有整数类型,结果类型为''type''。
后缀表达式后跟方括号[]中的表达式是下标 指定数组对象的元素。下标运算符[]的定义 是E1 [E2]与(*((E1)+(E2)))相同。