2016-01-08 9 views
10

Per l'eleganza, l'incapsulamento e lo sfruttamento di ADL (Argument Dependent Lookup) è comune definire una funzione all'interno dello spazio dei nomi dell'argomento della funzione.Qual è il miglior spazio dei nomi per un operatore binario?

Supponiamo di avere due librerie in uno spazio dei nomi diverso. Ci sono tre casi 1) uno fa parte di una libreria che io controllo e l'altro è di terze parti (ad esempio Boost), oppure 2) Controllo entrambi, o 3) Non ne controllo nessuno (basta scrivere il codice "glue").

ho qualcosa di simile,

namespace ns_A{ 
    struct A{...}; // something that looks like iostream 
} 
namespace ns_B{ 
    struct B{...}; 
} 

voglio "stream" B in A, qual è l'opzione migliore

namespace ???{ // what is more correct ns_A, or ns_B? 
    A& operator<<(A& a, B const& b){...} 
} 

o dovrei metterlo in entrambi gli spazi dei nomi?

namespace ns_B{ 
    A& operator<<(A& a, B const& b){...} 
} 
namespace ns_A{ 
    using ns_B::operator<<; 
} 

Quale è il miglior spazio dei nomi per definire una funzione binaria come questo?

(Vuol C++ 11 del namespace in linea cambiano ogni raccomandazione?)

(io uso l'esempio operator<< perché, a parità di condizioni si sembra intuitivamente essere meglio preferire namespace ns_B.)

+2

Non giocherellare con lo spazio dei nomi che non si controlla. – Walter

risposta

4

Puoi mettere il tuo operatore in uno spazio dei nomi e funzionerà. Come best practice, inseriscilo nel namespace che appartiene al tuo codice.

5

Nel caso 1, è semplice: mettilo nel namespace che controlli.

Nel caso 2, dipende dalla vostra scelta: qualsiasi cosa appaia più logica. Nel tuo esempio, preferirei ns_B.

L'unica situazione difficile è 3. Non è necessario aggiungere realmente a namespace. Se vuoi che la nuova funzionalità "colla" faccia parte del tuo terzo namespace mine, inseriscila naturalmente lì e qualsiasi utilizzo di tale funzionalità entro mine verrà risolto automaticamente. Naturalmente, questo non invierà ADL, ma non ce n'è bisogno, dal momento che tutto ciò che si desidera è utilizzare la nuova funzionalità entro mine, non da qualche altra parte.

1

Il mio suggerimento: Non utilizzare nessuno dei namespace. Codice in ns_A non è a conoscenza dell'esistenza di qualcosa in ns_A - non dipende da esso; quindi il codice relativo ai costrutti ns_B e ns_A non appartiene a ns_A. Lo stesso vale per ns_B, per simmetria.

tuo operator<< dovrebbe essere nel "meno spazio dei nomi comune" tra ns_A e ns_B, che è probabilmente non namespace (ma se è ns_Ans1::ns2 e ns_B è ns1::ns3 quindi utilizzare ns1).

Forzare codice in uno spazio dei nomi a cui non appartiene chiaramente è, a mio avviso, non elegante e interrompe l'incapsulamento, concettualmente. Per quanto riguarda ADL, penso che non dovresti aspettarti di più di quello che "lo spazio dei nomi meno comune" di ns_A e di ns_B ti offre.

+0

Sicuramente una grossa raccomandazione. Questa è un'opzione da considerare. La parte migliore, le cose positive su ADL continueranno a funzionare. – alfC

Problemi correlati