2009-11-02 1 views
23

Mi sembra che l'utilizzo di spazi dei nomi non aggiornati stia semplicemente creando problemi in seguito quando qualcuno inserisce un nuovo spazio dei nomi che ha lo stesso nome di uno spazio dei nomi di livello radice e altera misteriosamente il significato di molti programmi. Quindi, perché la gente dice sempre std:: anziché ::std::. Hanno davvero intenzione di dire "Voglio usare qualsiasi cosa std è utile, non quella di root".?Perché tutti usano dichiarazioni di namespace non aggiornate (ad es. Std :: not :: std: :)?

Ecco un esempio di ciò che intendo:

In fred/foo.h:

#include <string> 

namespace fred { 

class Foo { 
public: 
    void aPublicMember(const std::string &s); 
}; 

} // end namespace fred 

In fred/Bar.h:

namespace fred { 
namespace std { // A standard fred component 

class string { // Something rather unlike the ::std::string 
    // ... 
}; 

} // namespace std 

class Bar { 
public: 
    void aPublicMember(std::string &s); 
}; 

} // namespace fred 

In oops.cpp:

#include <string> 
#include "fred/Bar.h" 
#include "fred/Foo.h" // Oops, the meaning of Foo is now different. 

È quello che le persone vogliono o sono Mi manca qualcosa?

E forse dici che non dovresti nominare mai uno spazio nomi std. E va tutto bene, ma per quanto riguarda un altro spazio dei nomi di root? Qualunque spazio dei nomi di livello radice che qualcuno abbia mai definito è sempre off-limits per un nome di spazio secondario?

Per chiarire, non considererò alcuna risposta che mi dica che std è speciale perché l'ho usato solo come esempio. Sto parlando di un problema generale e sto usando std come supporto per illustrarlo, anche se ammetto che è un oggetto piuttosto sorprendente.

risposta

14

Il motivo pratico per gli spazi dei nomi non aggiornati è che un livello di spazi dei nomi è in genere sufficiente. Quando non lo è, di solito verrà utilizzato un secondo livello per i dettagli di implementazione. E infine, anche quando si utilizzano più livelli, vengono comunque specificati in modo implicito dal livello di root. vale a dire. anche all'interno dello spazio dei nomi ns1, in genere si fa riferimento a ns1::ns2::foo anziché ns2::foo o ::ns1::ns2::foo.

Quindi, per questi tre motivi il modulo ::ns1 è ridondante nei casi normali. L'unico caso in cui lo considererei sarebbe nelle presentazioni a Boost, perché come autore Boost non saprò dove verrà utilizzato il mio software.

+0

Lo accetterò perché è il più vicino a una vera risposta. Penso che l'altro sia stato appena votato più in alto perché era più divertente. :-) Sospetto che avrei dovuto scegliere un esempio diverso, o non aver fatto la domanda nel modo in cui l'ho fatto. – Omnifarious

2

Nel caso di std non assumerei nessun altro spazio dei nomi con lo stesso nome, stesse classi ma con un significato diverso.

In altri casi, il numero iniziale :: sembra appena brutto e rende il codice di lettura più difficile (secondo me). Gli scontri nello spazio dei nomi sono troppo rari per mettere lo :: davanti a tutto.

3

Questo è molto artificiale:

namespace fred { 
namespace std { // A standard fred component 

class string { // Something rather unlike the ::std::string 
    // ... 
}; 

} // namespace std 
} // namespace fred 

Questa Fred non sarebbe in grado di spiegare perché lo ha fatto a tutta la squadra.

Per rispondere alla tua domanda: le persone omettono prima "::" perché è un'abitudine, che fa risparmiare tempo e perché è più facile aspettarsi che quando lo spazio dei nomi viene usato ovunque, allora tale nome è assoluto, non relativo.

+3

Fred ha bisogno di essere colpito da un LART. – user7116

7

Perché la gente dice sempre std ::

Non sempre. Io uso string e using ::std::string. Quindi niente di male se ci sarà fred::std::string, perché io uso ancora std::string. Nei piccoli file cpp potrebbe essere anche using namespace ::std.Esempio:

#include <iostream> 
using ::std::string; 
//using namespace ::std; // good for small cpp-files 

int main() 
{ 
    string s = "sometext"; // no leading ::std 
} 

si dovrebbe solo non citarne namespace std

Sì, non si dovrebbe dare un nome a std spazio dei nomi personalizzato.

2

Un sacco di codice è scritto nel namespace globale. Se qualcuno veramente ridefinisce :: std ::, non importa come lo si fa in quel tipo di codice.

Inoltre, lo scenario è improbabile e facile da aggirare. In primo luogo, la convenzione in quanto esisteva un "std" era che non si utilizza quel nome. In secondo luogo, se si dovesse incontrare un pacchetto che definisce lo spazio dei nomi 'std', basta fare questo:

#include <package_name.hpp> 

namespace package_name { 
    using namespace std; 
} 

namespace my_app { 
    class my_class : public package_name::class_of_something {}; 
} 

o qualcosa di simile. Potrebbe essere necessario nominare esplicitamente :: std come std. Il mio punto è questo: le persone continuano a usare sempre lo "std ::" non ancorato perché anche le conseguenze del caso peggiore non sono un grosso problema e improbabili.

2

OK, tu dici che std è solo un esempio. Ma a me sembra che la tua domanda sia applicabile solo a un caso in cui qualcuno fa qualcosa di altrettanto malvagio che lo sostituisce std.

Lasciatemi fare un altro esempio:

namespace logging 
{ 
    // Logs to local file 
} 

namespace server 
{ 
    namespace logging 
    { 
     // Logs to remote destination 
    } 
} 

namespace client 
{ 
    namespace logging 
    { 
     // Logs to local file and to screen 
    } 
} 

In questo caso, non anteponendo :: risultati nel comportamento di default.

+0

Questa è un'ottima ragione per cui in determinate circostanze dovrebbero essere utilizzati spazi dei nomi relativi, sono assolutamente d'accordo. – Omnifarious

+0

Ma nella tua classe, cosa succede quando qualcuno crea uno spazio dei nomi 'server' nel loro spazio dei nomi 'client' per riferirsi a cose relative al server a cui il cliente importa? – Omnifarious

+0

@Omnifarious Volevo solo dimostrare che le risposte dipendono fortemente dall'esempio che date per questa domanda. Ad ogni modo: direi che sarebbe quasi malvagio quanto creare il proprio spazio dei nomi std. Si potrebbe usare "servocom" se si tratta di comunicazione o "serverconf" per la configurazione ecc. Invece del solo "server". – foraidt

33

Allora, Perché la gente dice sempre std :: anziché :: std ::

Probabilmente perché non hanno mai realmente avuto problemi con l'ambiguità a causa di esso.

Sulla stessa falsariga: non ho mai dovuto includere "terra" nel mio indirizzo e non lo farò.

Devi tracciare la linea da qualche parte, e questo è un ragionevole presupposto che gli altri non creino i propri spazi dei nomi standard, o almeno che una libreria che non sia molto popolare. :)

+0

+1 per umorismo [15 char filler] – foraidt

+2

* ridacchia * Beh, se vivessi ad Andromeda e volessi fare riferimento a qualcuno sulla Terra, probabilmente salterò il "gruppo locale", ma includo la "Via Lattea" , "Sistema Sol" e "Terra". – Omnifarious

+2

ma l'umanità ha bisogno di evolvere tecnicamente questa roccia prima che questa sia una preoccupazione – Hardryv

1

Allo stesso modo che i nomi con prefisso _ sono riservati, considerare std:: buono come prenotato.

+0

Anche se per essere pedante, non tutti i nomi preceduti da un carattere di sottolineatura sono riservati. – GManNickG

+0

Sì, non tutto. Se qualcuno fosse interessato alla piena goriness, [leggi questo] (http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) –