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 的一些真正古老的残余?此外,是否需要两次转换才能到达那里-首先从DictionaryRef
到bool
,然后从bool
到int
?
【问题讨论】:
代码编译了吗? 我在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]的主要内容,如果未能解决你的问题,请参考以下文章