Обоснование принуждения некоторых операторов к участию - PullRequest
22 голосов
/ 15 октября 2010

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

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

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

Ответы [ 2 ]

19 голосов
/ 15 октября 2010

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

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

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

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

Cheers & hth.,

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

2 голосов
/ 15 октября 2010

Этот поток на 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();                   
}
...