Überlegenheit des unbenannten Namespace gegenüber dem statischen?


Antworten:


133

Sie beziehen sich grundsätzlich auf den Abschnitt §7.3.1.1 / 2 aus dem C ++ 03 Standard,

Die Verwendung des statischen Schlüsselworts ist veraltet, wenn Objekte in einem Namespace-Bereich deklariert werden. Der unbenannte Namespace bietet eine überlegene Alternative.

Beachten Sie, dass dieser Absatz bereits in C ++ 11 entfernt wurde. staticFunktionen sind standardmäßig nicht mehr veraltet!

Unbenannte Namespaces sind dem statischen Schlüsselwort jedoch überlegen, vor allem, weil das Schlüsselwort staticnur für die Variablendeklarationen und -funktionen gilt, nicht für die benutzerdefinierten Typen .

Der folgende Code ist in C ++ gültig

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

Dieser Code ist jedoch NICHT gültig:

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

Die Lösung lautet also: Unbenannter Namespace.

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

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

Beachten Sie außerdem, dass die Verwendung des statischen Schlüsselworts beim Deklarieren von Objekten in einem Namespace-Bereich (gemäß Standard) veraltet ist.


11
Im Allgemeinen ermöglicht ein unbenannter Namespace eine externe Verknüpfung. Dies ermöglicht die Deklaration der Klasse "Lokal zu Übersetzungseinheit". Es erlaubt auch, zB eine externe Verknüpfungszeichenfolgenkonstante als Vorlagenargument zu verwenden.
Prost und hth. - Alf

10
Wie Fred Nurk in einer anderen Ihrer Antworten deprecatedbemerkt hat, wurde diese Bemerkung anscheinend aus der neuesten C ++ 0x FCD (n3225) entfernt.
Matthieu M.

36
Sie beantworten
Ihre

11
Was wäre der Unterschied zur Definition der Klasse in der CPP (kein anonymer Namespace, keine statische)?
Luchian Grigore

6
@LuchianGrigore Verbindungsprobleme in Fall 2 .cppdefinieren eine Klasse mit demselben Namen.
Xaqq

8

Damit ist ein interessantes Problem verbunden:

Angenommen, Sie verwenden ein staticSchlüsselwort oder einen Namen ohne Namen namespace, um eine Funktion innerhalb des Moduls (Übersetzungseinheit) zu erstellen, da diese Funktion vom Modul intern verwendet werden soll und außerhalb des Moduls nicht zugänglich ist. (Unbenannte namespaces haben den Vorteil, dass neben Funktionen auch Daten- und Typdefinitionen intern sind).

Mit der Zeit wird die Quelldatei der Implementierung Ihres Moduls größer, 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 haben Sie ein Problem: Diese Funktionen können sich nicht mehr staticauf das Modul staticbeziehen , da sie sich nicht auf das Modul beziehen , sondern auf die Quelldatei (Übersetzungseinheit). Sie müssen sie nicht aktivieren static, damit von anderen Teilen (Objektdateien) dieses Moduls auf sie zugegriffen werden kann. Dies bedeutet aber auch, dass sie für das Modul nicht mehr verborgen / privat sind: Durch die externe Verknüpfung können sie von anderen Modulen aus aufgerufen werden, was nicht Ihre ursprüngliche Absicht war.

Unbenannt namespacewürde dieses Problem auch nicht lösen, da es auch für eine bestimmte Quelldatei (Übersetzungseinheit) definiert ist und von außen nicht zugänglich ist.

Es wäre toll , wenn man angeben könnte , dass einige namespaceist private, das heißt, was in ihm definiert ist, verwendet werden soll intern vom Modul zu ihm gehört. Aber natürlich hat C ++ kein Konzept wie "Module", sondern nur "Übersetzungseinheiten", die eng an die Quelldateien gebunden sind.


3
Es wäre sowieso ein Hack und eine eingeschränkte Lösung, aber Sie könnten die CPP-Datei (en) mit den internen statischen oder Namespace-Funktionen in Ihre 'Haupt'-CPP-Dateien aufnehmen. Schließen Sie dann diese 'Satellit'-CPP-Datei (en) vom Build aus 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

Ist die Verwendung der Vererbung mit privat / geschützt / öffentlich mit statischen Funktionen nicht die Lösung?
Ali

C ++ 20 führt Module ein, die Ihr Problem lösen.
LF

5

Der C ++ Standard liest in Abschnitt 7.3.1.1 Unbenannte Namespaces, Absatz 2:

Die Verwendung des statischen Schlüsselworts ist veraltet, wenn Objekte in einem Namespace-Bereich deklariert werden. Der unbenannte Namespace bietet eine überlegene Alternative.

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


4
Nein, das tut es nicht. Ein Entwurf tat es. Und ein weiterer Entwurf sehr bald danach kehrte diese dumme Änderung zurück.
underscore_d
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.