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

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

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

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

2 ответа

Решение

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

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

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

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

Ура & hth.,

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

В этой теме на comp.std.C++ обсуждается вопрос.

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

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

Стараясь избежать ситуации, когда:

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();                   
}
Другие вопросы по тегам