C++ – Why Isn’t the Arrow Operator Just an Alias of *?

coperators

In c++, the * operator can be overloaded, such as with an iterator, but the arrow (->) (.*) operator does not work with classes that overload the * operator. I imagine that the preprocessor could easily replace all instances of -> with (*left).right, and that would make iterators nicer to implement. is there a practical reason for -> to be different, or is that just a peculiarity of the language/designers?

Best Answer

The rule that foo->bar equals (*foo).bar only holds for the builtin operators.

Unary operator * doesn't always have the pointer dereference semantics. I could make a library in which it means matrix transposition, zero-or-more parser matches, or pretty much anything.

It would make the language more bothersome if anything that overloads unary operator * would suddenly gain an operator -> you did not ask for, with semantics that might not make sense.

operator -> is separately overloadable, so if you want one, you can overload one with minimal effort.

Also note that such an overload would have some rather interesting properties, like automatically chaining operator -> calls until one in the chain returns a raw pointer. This is quite useful for smart pointers and other proxy types.

#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
#include <iostream>
#include <ostream>

struct Foo
{
    boost::shared_ptr<std::string> operator -> () const
    {
        return boost::make_shared<std::string>("trololo");
    }
};

int main()
{
    Foo foo;
    std::cerr << foo->size() << std::endl;
}