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

时间:2015-07-07 13:11:17

标签: c++ visual-studio visual-studio-2013

我有以下课程:

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的一些非常古老的残余?此外,它不需要两次转换才能实现 - 首先从DictionaryRefbool,从boolint

1 个答案:

答案 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)))相同。