Justificativa de impor alguns operadores a serem membros

Existem 4 operadores em C ++ que podem ser sobrecarregados, mas não podem ser sobrecarregados como funções independentes (também conhecidas como não-membros, independentes). Esses operadores são:

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

Este tópico explica perfeitamente a lógica por trás da proibição do operator = ser uma function não-membro. Alguma idéia sobre os outros três?

Os quatro operadores mencionados no lançamento original, = , () , -> e [] , devem, de fato, ser implementados como funções-membro não-estáticas (respectivamente C ++ 98 §13.5.3 / 1, §13.5.4 / 1 , §13.5.5 / 1 e §13.5.6 / 1).

A lógica de Bjarne Stroustrup era, se bem me lembro de debates anteriores sobre o assunto, manter alguma sanidade na linguagem, ou seja, ter pelo menos algumas coisas em que você poderia confiar, não importa o quanto Someone Else errou ao definir operadores não-membros. classs.

Não tenho certeza se concordo totalmente que a restrição realmente ajuda com isso, mas.

EDIT : Eu consultei Bjarne Stroustrup sobre isso (ele é sempre útil), mas parece que as aparentes inconsistências das regras não são mais do que um caso de acidente histórico congelado. Ele observa que “parece pior agora do que era então porque nossas regras para lvalues ​​e referências mudaram desde que as regras de sobrecarga foram formuladas. Eu tentei olhar para essa questão novamente um par de anos atrás, mas ficou sem tempo antes de produzir um proposta completa “.

Cheers & hth.

PS: O livro “Design e Evolução de C ++” é ótimo para esse tipo de pergunta, mas infelizmente não tenho isso.

Este tópico no comp.std.c ++ discute a questão.

Francis Glassborow, que estava no comitê, declarou:

Os designers de linguagem não queriam oferecer suporte a conversões e promoções no operando esquerdo de operator =, nem no operando de () e [].

Tentando evitar a situação em que:

 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(); }