2010-09-02 12 views
13

Voglio sovraccaricare operator<< per la mia classe. Devo aggiungere questa definizione sovraccaricata allo spazio dei nomi std? (poiché lo ostream operator<< fa parte dello spazio dei nomi std) O dovrei semplicemente lasciarlo nello spazio dei nomi globale?Dove dovrebbero essere collocati i sovraccarichi dell'operatore non membro?

In breve:

class MyClass { 

}; 

namespace std { 
    ostream& operator<< (ostream& Ostr, const MyClass& MyType) {} 
} 

O

class MyClass { 

}; 

std::ostream& operator<< (std::ostream& Ostr, const MyClass& MyType) {} 

Quale è più appropriato e perché? Grazie in anticipo per le vostre risposte.

risposta

25

È necessario inserire il sovraccarico dell'operatore nello stesso spazio dei nomi della classe.

Ciò permetterà all'operatore di essere trovato durante la risoluzione di sovraccarico utilizzando la ricerca argomento-dipendente (beh, in realtà, dal momento che ostream è nel namespace std, il sovraccarico di sovraccarico potrebbe anche essere trovato se lo metti in namespace std, ma non v'è nessuna ragione per farlo).

Dal punto di vista delle buone pratiche di progettazione, il sovraccarico dell'operatore è più una parte dell'interfaccia della vostra classe rispetto all'interfaccia di ostream, quindi appartiene allo stesso spazio dei nomi della classe (vedere anche Herb Sutter Namespaces and the Interface Principle).

Dal punto di vista della scrittura di codice conforme agli standard e portatile, non è possibile inserire il sovraccarico dell'operatore nello spazio nomi std. Sebbene sia possibile aggiungere specializzazioni di modelli per entità definite dall'utente allo spazio nomi std, non è possibile aggiungere sovraccarichi di funzioni aggiuntivi.

+1

+1 Inoltre, collegamento obbligatorio: http://en.wikipedia.org/wiki/Argument-dependent_lookup –

+0

è l'ultima frase propriamente corretto considerando la risposta e la citazione di Sam dalla standard. – Chubsdad

+3

@chubsdad: Sì, penso di sì: si _can_ aggiungere specializzazioni; non puoi aggiungere sovraccarichi. –

6

Non aggiungere allo spazio dei nomi standard. Motivo: se tutti lo facessero, lo spazio dei nomi standard avrebbe un mucchio di conflitti di nomi, il che vanifica lo scopo di uno spazio dei nomi.

Il tuo obiettivo è che la tua classe sia "ostream-able". Non è necessario che sia nello spazio dei nomi standard per farlo. Finché è in qualunque namepsace è dichiarata la tua classe, stai bene. Metterlo nello spazio dei nomi standard sarebbe una cattiva pratica.

+1

Sconfigge lo scopo del namespace 'std', che è per il codice di libreria standard C++. Quale codice utente non è. –

6

Non aggiungerlo allo spazio dei nomi std, posizionarlo nello stesso spazio dei nomi della classe. Lo scopo di uno spazio dei nomi è prevenire le collisioni. Lo standard dice

17.4.3.1 nomi riservati

E non è definito per un programma C++ per aggiungere dichiarazioni o definizioni per namespace std o spazi dei nomi all'interno namespace std, se non diversamente specificato . Un programma può aggiungere le specializzazioni del modello per qualsiasi modello di libreria standard allo std del namespace. Tale specializzazione (completa o parziale) di uno standard di biblioteca risultati di modello di comportamento indefinito meno che la dichiarazione dipende da un nome definito dall'utente di collegamento esterno ea meno che la specializzazione soddisfa i requisiti libreria standard per l'originale modello.

Problemi correlati