Perché l'operatore di freccia in C ++ non è solo un alias di *.?

18

In c ++, l'operatore * può essere sovraccaricato, ad esempio con un iteratore, ma l'operatore freccia (- >) (. *) non funziona con le classi che sovraccaricano l'operatore *. Immagino che il preprocessore possa facilmente sostituire tutte le istanze di - > con (* sinistra) .right, e questo renderebbe gli iteratori più facili da implementare. c'è una ragione pratica per - > essere diversi, o è solo una peculiarità del linguaggio / designer?

    
posta Jakob Weisblat 19.07.2012 - 17:05
fonte

3 risposte

16

La regola che foo->bar equivale a (*foo).bar vale solo per gli operatori incorporati.

Unario operator * non ha sempre la semantica della dereferenziazione puntatore. Potrei creare una libreria in cui significa trasposizione di matrici, zero o più corrispondenze di parser o praticamente niente.

Renderebbe il linguaggio più fastidioso se qualcosa che sovraccarichi unary operator * improvvisamente guadagnerebbe un operator -> che non hai richiesto, con una semantica che potrebbe non avere senso.

operator -> è sovraccarico separatamente, quindi se ne vuoi uno, puoi sovraccaricarlo con uno sforzo minimo.

Si noti inoltre che un tale sovraccarico avrebbe alcune proprietà piuttosto interessanti, come il concatenamento automatico delle chiamate operator -> finché uno nella catena non restituisce un puntatore raw. Questo è abbastanza utile per i puntatori intelligenti e altri tipi di proxy.

#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
#include <iostream>
#include <ostream>

struct Foo
{
    boost::shared_ptr<std::string> operator -> () const
    {
        return boost::make_shared<std::string>("trololo");
    }
};

int main()
{
    Foo foo;
    std::cerr << foo->size() << std::endl;
}
    
risposta data 19.07.2012 - 17:23
fonte
8

"Il linguaggio di programmazione C ++" descrive il fatto che questi operatori sono diversi in modo che possano essere, ma dice anche:

If you provide more than one of these operators, it might be wise to provide the equivalence, just as it is wise to ensure that ++x and x+=1 have the same effect as x=x+1 for a simple variable x of some class if ++,+=,=, and + are provided.

Quindi sembra che i progettisti linguistici abbiano fornito punti di sovraccarico separati perché potrebbe volerli sovraccaricare in modo diverso, piuttosto che assumere che sempre voglia che siano uguali.

    
risposta data 19.07.2012 - 17:26
fonte
7

Come regola generale, C ++ è progettato per favorire la flessibilità, quindi gli overload di * e -> sono separati. Anche se è abbastanza inusuale farlo, se vuoi fare abbastanza male puoi scrivere quei sovraccarichi per fare cose completamente diverse (ad esempio, potrebbe avere senso per una lingua specifica del dominio implementata all'interno di C ++).

Detto questo, gli iteratori fanno supportano entrambi gli usi. Nelle implementazioni antiche, potresti trovare una libreria che richiede (*iter).whatever invece di iter->whatever , ma se è così, questo è un bug nell'implementazione, non una caratteristica della lingua. Data la mole di lavoro necessaria all'implementazione di tutti i contenitori / algoritmi / iteratori standard, non sorprende che alcune versioni iniziali fossero in qualche modo incomplete, ma non erano mai state pensate per essere così.

    
risposta data 19.07.2012 - 17:18
fonte

Leggi altre domande sui tag