为什么调用箭头( - >)运算符失败?

joh*_*een 6 c++ operator-overloading

请考虑以下代码:

#include <iostream>

class Test
{
public:
    Test() : a{ 0 }
    {}

    void print() const
    {
        std::cout << "a : " << a << std::endl;
    }

    void operator->()
    {
        a = 5;
    }

    void operator++()
    {
        ++a;
    }

public:
    int a;
};

int main()
{
    Test a;
    a.print();

    // Increment operator
    a.operator++();      // CORRECT
    ++a;                 // CORRECT
    a.print();

    // Indirection operator
    a.operator->();      // CORRECT
    a->;                 // INCORRECT
    a.print();
}
Run Code Online (Sandbox Code Playgroud)

为什么对第二个->操作员的调用不正确?我知道这种用法->与一般用法不同,但这种用法是否被标准禁止?

P.W*_*P.W 10

在子部分类成员接入重载操作符从CPP标准草案(N4713)规定的:

16.5重载运算符
...
16.5.6类成员访问[over.ref]
1. operator->应该是不带参数的非静态成员函数.它实现了使用的类成员访问语法->.

postfix-expression -> template(opt) id-expression //This!!
postfix-expression -> pseudo-destructor-name
Run Code Online (Sandbox Code Playgroud)

表达式x->m被解释为类型为if (x.operator->())->m的类对象x,T如果T::operator->()操作符被重载决策机制选为最佳匹配函数(16.3).

如您所见,id-expression如果->操作员超载,则非常需要.


Swo*_*ish 6

类成员访问[expr.ref/1]§7.6.1.5/ 1:

  1. 后缀表达式后跟一个点.或箭头->,可选地后跟关键字模板([temp.names]),然后是id-expression,后缀表达式.评估点或箭头之前的后缀表达式 ; 该评估的结果id-expression一起确定整个后缀表达式的结果.

名称[expr.prim.id](§7.5.4):

id-expression:
unqualified-id
qualified-id

  1. id表达式是primary-expression的限制形式.[注意:后面会出现一个id表达式.和 - >运算符. - 结束说明]

  2. 只能使用表示非静态数据成员或类的非静态成员函数的id表达式:

    2.1.作为类成员访问的一部分,其中对象表达式引用成员的类或从该类派生的类,或
    2.2.形成指向成员([expr.unary.op])或
    2.3 的指针.如果该id-expression表示非静态数据成员,则它出现在未评估的操作数中.