Правило, 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;
}