2个重载具有类似的转换 - 内置运算符整数[指向对象的指针]

riv*_*riv 6 c++ visual-studio visual-studio-2013

我有以下课程:

class DictionaryRef {
public:
  operator bool() const;
  std::string const& operator[](std::string const& name) const;
  // ...
};
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用它:

DictionaryRef ref = ...;
ref["asdf"]; // error
Run Code Online (Sandbox Code Playgroud)

输出抱怨两个重载,但只列出一个:

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 *)'
Run Code Online (Sandbox Code Playgroud)

但是,将鼠标悬停在带下划线的部分上,弹出窗口告诉我第二个选项是built-in operator integer[pointer-to-object].显然它会考虑将对象转换为bool,然后使用神秘的运算符int[char const*].我之前从未听说过这个算子,但显然3["asdf"]是一样的"asdf"[3]?是否有人用这样的语法或者是由C一些真的老残?另外,是不是需要两次转换到那里-首先从DictionaryRefbool,并且他们boolint

Ser*_*sta 4

这是违反直觉的,但根据规范,下标是一个交换运算符。

\n\n

第 5.2.1 段下标表示:

\n\n

后缀表达式后面跟着方括号中的表达式就是后缀表达式。其中一个表达式应具有类型为 T\xe2\x80\x9d 的 \xe2\x80\x9c 数组或指向 T\xe2\x80\x9d 的指针,另一个应具有无范围枚举或整数类型。结果的类型为 \xe2\x80\x9cT。\xe2\x80\x9d 类型 \xe2\x80\x9cT\xe2\x80\x9d 应为完全定义的对象类型。64\n表达式 E1[E2] 为(根据定义)与 *((E1)+(E2)) 相同

\n\n

这意味着当x是一个数组和i一个积分时,x[i] is *((x)+(i))并且也是i[x]

\n\n

这就是操作符的原因int[char const *]:它与操作符是相同的操作(char const *)[int]

\n\n

作为参考,C 支持相同的功能:在 C 语言规范中,关于数组下标的 6.5.2.1 段落还说:

\n\n

其中一个表达式应具有类型 \xe2\x80\x98\xe2\x80\x98 完成对象类型\xe2\x80\x99\xe2\x80\x99 的指针,另一个\n表达式应具有整数类型,并且结果具有类型\xe2\x80\x98\xe2\x80\x98type\xe2\x80\x99\xe2\x80\x99。

\n\n

后缀表达式后跟方括号 [] 中的表达式是数组对象元素的下标指定。下标运算符[]\nis的定义是E1[E2]与(*((E1)+(E2)))相同。

\n