Я не понимаю, как это решает проблему: operator-
вызов по указателям уже имеет значение.
Вы бы определили operator-
для Foo*
аргументов, но это уже существует.
Тогда вам потребуется некоторая надуманная семантика, которая "при явном вызове с указателями вызывается арифметический оператор указателя. При вызове с объектными значениями l они распадаются на указатели, а затем вызывается перегруженная версия". Что, честно говоря, кажется гораздо более надуманным и гораздо менее интуитивным, чем просто добавление ссылок.
А затем внутри operator-
я получаю аргументы в качестве указателей, и тогда мне лучше разыменовать их, если мне нужно оттуда вызвать другой (или тот же) оператор. В противном случае я бы случайно закончил выполнение арифметики с указателями.
Вы предлагаете неявное преобразование, которое имеет другую семантику, чем выполнение преобразования самостоятельно. То есть:
Foo foo;
bar(foo);
выполняет неявное преобразование из Foo
в Foo*
, после чего вызывается функция с подписью void bar(Foo*)
.
Но этот код сделал бы что-то совершенно другое:
Foo foo;
bar(&foo);
, который также преобразуется в Foo*
, и также вызывает функцию с сигнатурой void bar(Foo*)
, но потенциально это может быть другая функция. (Например, в случае operator-
один будет оператором, перегруженным пользователем, а другой - стандартным арифметическим указателем.
А затем рассмотрите код шаблона. В целом, неявные преобразования делают шаблоны действительно болезненными, поскольку передаваемый тип может не соответствовать типу, с которым вы хотите работать.
Конечно, есть и более практические проблемы:
Ссылки позволяют оптимизировать, что невозможно с указателями. (Компилятор может предположить, что они никогда не равны нулю, и он может сможет лучше выполнять анализ псевдонимов)
Кроме того, код будет молча не работать, если не найден соответствующий operator-
. Вместо того, чтобы сказать , что , компилятор неявно начнет выполнять арифметику с указателями. Не нарушитель соглашения, но я действительно предпочитаю, чтобы ошибки, по возможности, выявлялись рано.
И одна из целей C ++ состояла в том, чтобы сделать его универсальным: избежать «магических» типов или функций. В реальном C ++ операторы - это просто функции с другим синтаксисом. С этим правилом у них также была бы другая семантика. (Что если оператор вызывается с синтаксисом функции? operator+(a, b)
?