Правило, foo->barрівне, (*foo).barсправедливо лише для вбудованих операторів.
Унар operator *не завжди має семантику відміни покажчика. Я міг би створити бібліотеку, в якій це означає перенесення матриці, нульове або більше парсерних збігів, або майже все, що завгодно.
Це зробило б мову набридливішою, якби щось, що перевантажує одинарне operator *, раптом отримає те, про що operator ->ви не просили, із семантикою, яка може не мати сенсу.
operator -> може завантажуватися окремо, тому якщо ви хочете, ви можете перевантажити її мінімальними зусиллями.
Також зауважте, що таке перевантаження має деякі досить цікаві властивості, як-от автоматичне operator ->ланцюг дзвінків, поки один із ланцюжків не поверне необроблений покажчик. Це досить корисно для розумних покажчиків та інших типів проксі.
#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;
}