2010-12-12 5 views
94

Wie sind unbenannte Namespaces dem Schlüsselwort static?Überlegenheit von unbenannten Namespace über statische?

+0

Ungenannte Namespaces sind jedoch laut Standardkomitee kein ausreichender Ersatz für _namespace-static_. [Es gibt immer noch ein paar Instanzen] (http://stackoverflow.com/q/8460327/183120), wo unbenannte Namespaces fehlschlagen und nur 'static' funktioniert. – legends2k

Antwort

100

Sie sind im Grunde $ 7.3.1.1/2 von der C++ Standard in den Abschnitt,

Die Verwendung des statischen Schlüsselwort ist veraltet, wenn Objekte in einem Namespacebereich deklarieren ; Der unbenannte Namespace bietet eine bessere Alternative.

Unbenannt Namespace ist überlegen statische Schlüsselwort, vor allem, weil das Schlüsselwort static nur auf dieVariablen Erklärungen und Funktionen, nicht an den benutzerdefinierten Typen gilt.

Der folgende Code ist gültig in C++

//legal code 
    static int sample_function() { /* function body */ } 
    static int sample_variable; 

Aber dieser Code ist nicht gültig:

//illegal code 
    static class sample_class { /* class body */ }; 
    static struct sample_struct { /* struct body */ }; 

So ist die Lösung, unbenannte-Namespace, der das ist,

//legal code 
    namespace 
    { 
     class sample_class { /* class body */ }; 
     struct sample_struct { /* struct body */ }; 
    } 

Hoffe es erklärt, warum unnamed-namespacestatic überlegen ist.

Beachten Sie auch, dass die Verwendung von statischem Schlüsselwort ist veraltet, wenn Objekte in einem Namespace Umfang (gemäß dem Standard) zu deklarieren.

+11

Allgemeiner ermöglicht ein unbenannter Namespace externe Verknüpfung. Dadurch wird die Deklaration der lokalen Einheit zur Übersetzungseinheit aktiviert. Es ermöglicht auch z.B. externe Verknüpfungszeichenfolgekonstante, die als Vorlageargument verwendet werden soll. –

+0

@Alf: Das stimmt. Danke für die Zugabe. :-) – Nawaz

+9

Wie von Fred Nurk auf einer anderen Ihrer Antwort bemerkt, scheint es, dass diese 'veraltet' Bemerkung aus dem letzten C++ 0x FCD (n3225) entfernt wurde. –

6

der C++ Standard 7.3.1.1 Unbenannt Namespaces in Abschnitt liest, Absatz 2:

Die Verwendung des statischen Schlüsselwort veraltet ist, wenn Objekte in einem Namespace Umfang, die ungenannte-Namespace bietet eine Deklaration überlegene Alternative.

Statisch gilt nur für Namen von Objekten, Funktionen und anonymen Vereinigungen, nicht zum Eingeben von Deklarationen.

+1

Nein, tut es nicht. Ein Entwurf hat es getan. Und ein anderer Entwurf, der sehr bald darauf zurückkehrte, kehrte diese alberne Änderung zurück. –

5

Es ist ein interessantes Problem im Zusammenhang mit dieser:

Angenommen, Sie verwenden static Stichwort oder unbenannte namespace eine Funktion innerhalb des Moduls (Übersetzungseinheit) zu machen, da diese Funktion durch die intern werden soll Modul und nicht außerhalb davon zugänglich. (Unbenannt namespace s haben den Vorteil, Daten und Typdefinitionen auch intern neben Funktionen zu machen).

Mit der Zeit wird die Quelldatei der Implementierung Ihres Moduls groß und Sie möchten sie in mehrere separate Quelldateien aufteilen, um den Code besser zu organisieren, die Definitionen schneller zu finden und unabhängig zu kompilieren .

Aber jetzt stellen Sie ein Problem: Diese Funktionen nicht mehr static an das Modul sein können, weil static eigentlich nicht den Modul beziehen, sondern auf die Quelldatei (Übersetzungseinheit). Sie sind gezwungen, sie nicht zu static zu machen, damit sie von anderen Teilen (Objektdateien) dieses Moduls aus zugänglich sind. Das bedeutet aber auch, dass sie nicht mehr versteckt/privat für das Modul sind: Sie können externe Verbindungen haben, auf die Sie von anderen Modulen zugreifen können, was ursprünglich Ihre Absicht war.

Unbenannt namespace würde dieses Problem nicht lösen, da es auch für eine bestimmte Quelldatei (Übersetzungseinheit) definiert ist und nicht von außen zugegriffen werden kann.

Es wäre großartig, wenn man angeben könnte, dass einige namespaceprivate ist, das heißt, was auch immer darin definiert ist, soll intern von dem Modul verwendet werden, zu dem es gehört. Aber natürlich hat C++ kein solches Konzept wie "Module", nur "Übersetzungseinheiten", die eng an die Quelldateien gebunden sind.

+2

Es wäre sowieso ein Hack und eine begrenzte Lösung, aber Sie könnten die CPP-Datei (en) mit den internen statischen oder Namespaced-Funktionen in Ihre "Haupt" cpp-Dateien einschließen. Dann schließen Sie diese 'Satelliten' CPP-Datei (en) aus dem Build und Sie sind fertig. Das einzige Problem, wenn Sie zwei oder mehr "Haupt" cpp-Dateien haben und beide diese coole Funktion aus einer der 'Satelliten' cpp-Dateien verwenden möchten ... – Sergey

Verwandte Themen