Laut dem Normungsausschuss sind unbenannte Namespaces jedoch kein ausreichender Ersatz für Namespace-Statics . Es gibt immer noch einige Fälle, in denen unbenannte Namespaces fehlschlagen und nur staticfunktionieren.
Legends2k
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 codestaticint sample_function(){/* function body */}staticint sample_variable;
Dieser Code ist jedoch NICHT gültig:
//illegal codestaticclass sample_class {/* class body */};staticstruct sample_struct {/* struct body */};
Die Lösung lautet also: Unbenannter Namespace.
//legal codenamespace{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.
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.
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.
static
funktionieren.Antworten:
Sie beziehen sich grundsätzlich auf den Abschnitt §7.3.1.1 / 2 aus dem C ++ 03 Standard,
Beachten Sie, dass dieser Absatz bereits in C ++ 11 entfernt wurde.
static
Funktionen sind standardmäßig nicht mehr veraltet!Unbenannte Namespaces sind dem statischen Schlüsselwort jedoch überlegen, vor allem, weil das Schlüsselwort
static
nur für die Variablendeklarationen und -funktionen gilt, nicht für die benutzerdefinierten Typen .Der folgende Code ist in C ++ gültig
Dieser Code ist jedoch NICHT gültig:
Die Lösung lautet also: Unbenannter Namespace.
Hoffe es erklärt, warum warum
unnamed-namespace
überlegen iststatic
.Beachten Sie außerdem, dass die Verwendung des statischen Schlüsselworts beim Deklarieren von Objekten in einem Namespace-Bereich (gemäß Standard) veraltet ist.quelle
deprecated
bemerkt hat, wurde diese Bemerkung anscheinend aus der neuesten C ++ 0x FCD (n3225) entfernt..cpp
definieren eine Klasse mit demselben Namen.Damit ist ein interessantes Problem verbunden:
Angenommen, Sie verwenden ein
static
Schlüsselwort oder einen Namen ohne Namennamespace
, 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. (Unbenanntenamespace
s 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
static
auf das Modulstatic
beziehen , da sie sich nicht auf das Modul beziehen , sondern auf die Quelldatei (Übersetzungseinheit). Sie müssen sie nicht aktivierenstatic
, 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
namespace
wü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
namespace
istprivate
, 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.quelle
Der C ++ Standard liest in Abschnitt 7.3.1.1 Unbenannte Namespaces, Absatz 2:
Statisch gilt nur für Namen von Objekten, Funktionen und anonymen Vereinigungen, nicht für Typdeklarationen.
quelle