应用与指针相关的运算符时隐式转换为指针类型

use*_*520 7 c++ pointers

请考虑以下代码:

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 测试.

asc*_*ler 6

标准部分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->,必须始终是成员函数.)