Одна сильная сторона, которую я могу видеть, однако это можно обсудить, заключается в том, что сигнатура operator () выглядит и ведет себя одинаково для разных типов. Если бы у нас был класс Reporter, у которого был отчет по методу-члену (..), а затем другой класс Writer, у которого был метод-член write (..), нам пришлось бы писать адаптеры, если бы мы хотели использовать оба класса как возможно компонент шаблона какой-то другой системы. Все, что его волнует, - это передавать строки или что-то еще. Без использования оператора () с перегрузкой или написанием адаптеров специального типа вы не могли бы делать такие вещи, как
T t;
t.write("Hello world");
потому что T требует, чтобы была функция-член write, которая принимает все неявно преобразуемые в const char * (или, скорее, const char []). У класса Reporter в этом примере такого нет, поэтому T (параметр шаблона), являющийся Reporter, не скомпилируется.
Однако, насколько я вижу, это будет работать с разными типами
T t;
t("Hello world");
тем не менее, он все еще явно требует, чтобы тип T определил такой оператор, поэтому у нас все еще есть требование к T. Лично я не думаю, что это слишком странно с функторами, поскольку они обычно используются, но я бы предпочел увидеть другие механизмы для этого поведения. В таких языках, как C #, вы можете просто передать делегат. Я не слишком знаком с указателями на функции-члены в C ++, но могу предположить, что вы можете добиться такого же поведения и там.
Кроме поведения синтетического сахара, я не вижу сильных сторон перегрузки операторов для выполнения таких задач.
Я уверен, что есть более сознательные люди, у которых есть более веские причины, чем у меня, но я подумал, что выложу свое мнение, чтобы поделиться с вами остальными.