2008-12-10 12 views
34

Jemand behauptet heute auf SO, dass Sie nie anonyme Namespaces in Header-Dateien verwenden sollten. Normalerweise ist das korrekt, aber ich glaube mich daran zu erinnern, dass mir jemand gesagt hat, dass eine der Standardbibliotheken anonyme Namespaces in Header-Dateien verwendet, um irgendeine Art von Initialisierung durchzuführen.Verwendet für anonyme Namespaces in Header-Dateien

Erinnere ich mich richtig? Kann jemand die Details ausfüllen?

+1

Sehen Sie diese Diskussion: [http://stackoverflow.com/questions/357404/anonynous-namespaces](http://stackoverflow.com/questions/357404/anonynous-namespaces) –

+0

das ist der Faden wo er diese Information von diesem anonymen Namespaces in Kopfzeilen hat, ist schlecht –

+0

Ich kann nichts in diesem Thread über die Verwendung in Header-Dateien finden. Kann jemand erklären, warum das falsch ist? Und gilt es immer noch in C++ 11? – baruch

Antwort

20

Die einzige Situation, in der ein namenlos Namespace in Header nützlich sein kann, ist, wenn Sie Code als Header-Dateien nur verteilen möchten. Zum Beispiel ist eine große eigenständige Untergruppe von Boost reine Header.

Das Token ignore für Tupel, in einer anderen Antwort erwähnt ist ein Beispiel, die _1, _2 usw. Bind Platzhalter sind andere.

+0

Ich denke, du hast einen guten Punkt damit gemacht. –

+0

Sie sollten keinen anonymen Namespace dafür verwenden, da sie in der endgültigen Kompilierungseinheit zusammen minimiert sind und möglicherweise zu Namespace-Konflikten führen. Verwenden Sie stattdessen einen Namen, der per Konvention bedeutet, dass die Inhalte Implementierungsdetails sind. Boost zum Beispiel verwendet 'detail'. – thehouse

+0

@thehouse Sie scheinen missverstanden zu haben, wie Boost die anonymen Namespaces verwendet. 'ignore' und' _1', '_2' usw. sind öffentliche Symbole - sie gehören nicht ins Detail. Aber ich stimme zu, dass ein Detail-Namespace normalerweise die richtige Wahl für die Entsprechung eines Headers eines anonymen Namespace ist. –

2

Ich kann wirklich keinen positiven Nutzen aus der Verwendung von anonymen Namespaces in Headern sehen. Die Verwirrung, die sich aus der gleichen Symbolerklärung ergeben kann, bedeutet im Wesentlichen eine andere Sache in den Kompilierungseinheiten, die diesen Header enthalten, wäre ein garantierter Weg, vorzeitig und schmerzhaft kahl zu gehen.

0

Wenn es Initialisierung ist, wäre es wahrscheinlich ein iostream s Header (wie istream, ios, etc.).

13

Ich sehe keinen Sinn darin, einen anonymen Namespace in eine Header-Datei zu setzen. Ich habe den Standard und die libstdC++ Header grep, hat keine anonymen Namensräumen abgesehen von einer in der tuple Header (C++ 1x Sachen):

// A class (and instance) which can be used in 'tie' when an element 
    // of a tuple is not required 
    struct _Swallow_assign 
    { 
    template<class _Tp> 
     _Swallow_assign& 
     operator=(const _Tp&) 
     { return *this; } 
    }; 

    // TODO: Put this in some kind of shared file. 
    namespace 
    { 
    _Swallow_assign ignore; 
    }; // anonymous namespace 

Das ist so können Sie tun

std::tie(a, std::ignore, b) = some_tuple; 

Elemente des some_tuple werden den Variablen auf der linken Seite zugewiesen (siehe here), eine ähnliche Technik wird für this Iterator verwendet. Das zweite Element wird ignoriert.

Aber wie sie sagen, sollte es in eine CPP-Datei eingefügt werden und die eine Instanz sollte von allen Benutzern geteilt werden. Sie würden wie diese dann eine Erklärung von ihm in den Kopf gesetzt:

extern _Swallow_assign ignore; 
+0

C++ 1x? Habe ich etwas verpasst? –

+0

nächste C++ Version –

+0

Sutter nennt es immer noch C++ 0x (http://herbsutter.wordpress.com/2008/10/28/september-2008-iso-c-standards-meeting-the-draft-has-landed -und-ein-neuer-convener /). –

4

Ich habe gesehen, es verwendet, um einen Standardwert für eine Variable in verschiedenen Übersetzungseinheiten bereitzustellen. Bei Namenskonflikten kann es jedoch zu einem unerwarteten Verhalten kommen.

Beispiel

a.hpp

namespace 
{ 
    const char name[] = "default"; 
} 
// This macro will hide the anonymous variable "name" 
#define SET_NAME(newname) \ 
static const char name[] = newname; 

b.cpp

#include "a.hpp" 
SET_NAME("file b") // name is "file b" in this translation unit 

c.cpp

d.cpp

#include "a.hpp" 
// name is "default" in this translation unit 

e.cav

#include "a.hpp" 
static const char name[] = "unintended"; 
// accidently hiding anonymous name 
Verwandte Themen