Подтвердить что ты не робот

Обоснование принуждения некоторых операторов к участию

В С++ есть 4 оператора, которые могут быть перегружены, но не могут быть перегружены как автономные (ака несимвольные, автономные) функции. Этими операторами являются:

  • operator =
  • operator ()
  • operator ->
  • operator []

Этот поток прекрасно объясняет, почему запрет operator = быть несимметричной функцией. Любые идеи о трех других?

4b9b3361

Ответ 1

Четыре оператора, упомянутые в исходной публикации, =, (), -> и [], действительно должны быть реализованы как нестатические функции-члены (соответственно С++ 98 §13.5.3/1, §13.5.4/1, §13.5.5/1 и §13.5.6/1).

Обоснование Бьярна Страуструпа было, как я помню из предыдущих дебатов по этому вопросу, сохранить некоторое здравомыслие в языке, то есть иметь хотя бы некоторые вещи, на которые вы могли бы положиться, независимо от того, насколько кто-то из вас прищурился, определив не-член операторов для существующих классов.

Я не уверен, что полностью согласен с тем, что ограничение действительно помогает с этим, но.

РЕДАКТИРОВАТЬ. Я консультировался с Бьярне Страуступом об этом (он всегда был полезным), но кажется, что кажущиеся несоответствия правил являются не более чем случаем замороженной исторической аварии. Он отмечает, что "теперь это выглядит хуже, чем тогда, потому что наши правила для lvalues ​​и ссылок изменились с тех пор, как были сформулированы правила перегрузки. Я попытался изучить этот вопрос еще пару лет назад, но у меня закончилось время, прежде чем создать полное предложение".

Приветствия и hth.,

PS: Книга "Дизайн и эволюция С++" отлично подходит для такого рода вопросов, но, к сожалению, у меня ее нет.

Ответ 2

Этот thread на comp.std.С++ обсуждает вопрос.

Фрэнсис Стеклобор, который был в комитете, заявил:

Разработчики языка не хотели поддерживать конверсии и акциях в левом операнде оператора =, а также на операнд() и [].

Попытка избежать ситуации, когда:

class A {};

class B { B(A& a) {} };

int operator()(B const& b) { return 0; }


int main(void)
{
    A a;

    // This works even though A doesn't have a () operator
    // It creates a temporary B and calls operator()(B& b)
    return a();                   
}