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?
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-nameAn expression
x->mis interpreted as(x.operator->())->mfor a class objectxof typeTifT::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.
Class member access [expr.ref/1] §7.6.1.5/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
An id-expression is a restricted form of a primary-expression. [ Note: An id-expression can appear after . and -> operators. — end note ]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With