Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this call to arrow (->) operator fail?

Consider the following code :

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

Why is the call to the second -> operator incorrect? I know this usage of -> is different from the general usage, but is such usage disallowed by the standard?

like image 803
johngreen Avatar asked Oct 12 '18 07:10

johngreen


2 Answers

The sub-section on Class member access from Overloaded Operators from CPP standard draft (N4713) states this:

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).

As you can see the id-expression is very much needed if the -> operator is overloaded.

like image 99
P.W Avatar answered Sep 19 '22 18:09

P.W


Class member access [expr.ref/1] §7.6.1.5/1:

  1. A postfix expression followed by a dot . or an arrow ->, optionally followed by the keyword template ([temp.names]), and then followed by an id-expression, is a postfix expression. The postfix expression before the dot or arrow is evaluated; the result of that evaluation, together with the id-expression, determines the result of the entire postfix expression.

Names [expr.prim.id] (§7.5.4):

id-expression:
unqualified-id
qualified-id

  1. An id-expression is a restricted form of a primary-expression. [ Note: An id-expression can appear after . and -> operators. — end note ]

  2. An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

    2.1. as part of a class member access in which the object expression refers to the member's class or a class derived from that class, or
    2.2. to form a pointer to member ([expr.unary.op]), or
    2.3. if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

like image 37
Swordfish Avatar answered Sep 17 '22 18:09

Swordfish