请考虑以下代码:
struct X
{
int x;
};
X xInstance;
class A
{
public:
operator X*()
{
return &xInstance;
}
};
int main()
{
A a;
*a = X(); // ok
a[0] = X(); // ok
// a->x = 0; // error
}
Run Code Online (Sandbox Code Playgroud)
A
有一个隐式转换为指针类型.我尝试在三个需要指针的上下文中使用它; 两个第一行很好,但是试图struct X
通过operator->
依赖隐式转换来引用一个字段是X*
行不通的.这是为什么?从概念上讲,在这种背景下有何operator[]
不同operator->
?
经过g++
6.3.0和VC++ 2017 测试.
标准部分13.6列出了代表内置运算符的"候选运算符函数",用于过载分辨率.当运算符@的至少一个子表达式具有类或枚举类型时,考虑用于重载解析的函数列表是非成员查找operator@
,成员查找operator@
和这些候选运算符函数的并集.
对于大多数运算符,候选运算符函数通常足以表示内置运算符允许的所有类型.例如,
对于每个cv限定或cv非限定对象类型T,存在表单的候选运算符函数
T& operator*(T*);
Run Code Online (Sandbox Code Playgroud)
对于每个cv限定或cv非限定对象类型T,存在表单的候选运算符函数
T& operator[](T*, std::ptrdiff_t);
T& operator[](std::ptrdiff_t, T*);
Run Code Online (Sandbox Code Playgroud)
当您编写*a
或者a[0]
相应的候选运算符函数赢得重载解析时,子表达式将转换为候选运算符函数的参数类型,然后应用普通的内置运算符规则.
但是,该部分未列出任何候选运算符函数operator->
.因此,如果a
有类类型,唯一可能的函数a->x
是成员查找a.operator->()
.(非成员查找不适用于operator->
,必须始终是成员函数.)