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

6

考虑以下代码:

#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();
}

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

1
这被添加到了我从未想过的事情清单上。谢谢你。=P - WhozCraig
1
可能有点直观地认为a.operator->()是一个函数调用,而a->(*a).的语法糖。 - Marco A.
1
a->; 是语法错误。操作符重载不能创建新的语法,它只是为现有的语法提供不同的行为。 - M.M
3个回答

10

C++标准草案(N4713)中重载运算符类成员访问子章节如下:

16.5 Overloaded operators
...
16.5.6 Class member access [over.ref]
1. operator-> shall be a non-static member function taking no parameters. It implements the class member access syntax that uses ->.

postfix-expression -> template(opt) id-expression //This!!
postfix-expression -> pseudo-destructor-name

An expression x->m is interpreted as (x.operator->())->m for a class object x of type T if T::operator->() exists and if the operator is selected as the best match function by the overload resolution mechanism (16.3).

如您所见,如果 -> 操作符被重载,那么 id-expression 是非常必要的。


6

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

  1. 后缀表达式后面跟着一个点 . 或者箭头 ->,可选择性地跟着关键字 template ([temp.names]),然后跟着一个id-expression,这是一个后缀表达式。点或箭头之前的后缀表达式将被求值;该求值结果加上id-expression一起确定整个后缀表达式的结果

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

id-expression:
unqualified-id
qualified-id

  1. id-expressionprimary-expression的一种限制形式。[注意:id-expression可以出现在点和箭头运算符之后。-end note]

  2. 表示非静态数据成员或非静态成员函数的id-expression只能在以下情况下使用:

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


1

正如M.M所说,“a->;”是一个语法错误。一个没有参数的非静态成员运算符函数是一个前缀(例如operator++();后缀是operator++(int))a.operator->();应该是->a;(哇!),但这又是一个语法错误。标准规定了细节...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接