2 个重载有类似的转换 - 内置运算符 integer[pointer-to-object]

Posted

技术标签:

【中文标题】2 个重载有类似的转换 - 内置运算符 integer[pointer-to-object]【英文标题】:2 overloads have similar conversions - built-in operator integer[pointer-to-object] 【发布时间】:2015-07-07 13:11:17 【问题描述】:

我有以下课程:

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

【问题讨论】:

代码编译了吗? 我在DictionaryRef 类中没有看到采用istring 的方法;您能否发布所有相关代码以便我们更好地帮助您? @RedRoboHood: [] 运算符实际上采用 istring (这是一个 typedef'd string_base 具有不区分大小写的特征),我只是忘记在错误消息中将其编辑出来,但如果我使用常规字符串。代码已完成,我可以将其粘贴到一个新项目中并得到相同的错误。 不,我在该类中没有任何其他运算符。正如我所说,如果我将该类声明(字面意思是,没有额外的成员代替 //...)复制到一个新项目中,我仍然会遇到同样的错误。 operator bool() 标记为 explicit 也应该可以解决您的问题(在 C++11 中)。 【参考方案1】:

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

第 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)))。

【讨论】:

以上是关于2 个重载有类似的转换 - 内置运算符 integer[pointer-to-object]的主要内容,如果未能解决你的问题,请参考以下文章

赋值运算符重载有类似的转换(仅在 VS 中)

C++ 重载转换运算符

操作重载与类型转换C++

操作重载与类型转换C++

操作重载与类型转换C++

重载运算符