Unbenannte Namespaces sind ein Dienstprogramm, um eine Bezeichner-Übersetzungseinheit lokal zu machen. Sie verhalten sich so, als würden Sie einen eindeutigen Namen pro Übersetzungseinheit für einen Namespace auswählen:
namespace unique { /* empty */ }
using namespace unique;
namespace unique { /* namespace body. stuff in here */ }
Der zusätzliche Schritt zur Verwendung des leeren Körpers ist wichtig, sodass Sie bereits innerhalb des Namespace-Körpers auf solche Bezeichner verweisen können ::name
, die in diesem Namespace definiert sind, da die using-Direktive bereits stattgefunden hat.
Dies bedeutet, dass Sie kostenlose Funktionen haben können, die (zum Beispiel) aufgerufen werden und help
in mehreren Übersetzungseinheiten vorhanden sein können und die zum Zeitpunkt der Verknüpfung nicht zusammenstoßen. Der Effekt ist fast identisch mit der Verwendung des static
in C verwendeten Schlüsselworts, das Sie in die Deklaration der Bezeichner einfügen können. Unbenannte Namespaces sind eine überlegene Alternative, da sie sogar eine Typübersetzungseinheit lokalisieren können.
namespace { int a1; }
static int a2;
Beide a
sind lokale Übersetzungseinheiten und stoßen zur Verbindungszeit nicht zusammen. Der Unterschied besteht jedoch darin, dass der a1
im anonymen Namespace einen eindeutigen Namen erhält.
Lesen Sie den ausgezeichneten Artikel bei comeau-computer. Warum wird ein unbenannter Namespace anstelle von statischem verwendet? ( Archive.org Spiegel ).
Johannes Schaub - litb
quelle
static
. Kannst du bitte auch mit vergleichen__attribute__ ((visibility ("hidden")))
?Wenn sich etwas in einem anonymen Namespace befindet, bedeutet dies, dass es für diese Übersetzungseinheit lokal ist (CPP-Datei und alle darin enthaltenen Elemente). Wenn ein anderes Symbol mit demselben Namen an anderer Stelle definiert wird, liegt kein Verstoß gegen die One Definition Rule (ODR) vor.
Dies entspricht der C-Methode für eine statische globale Variable oder statische Funktion, kann jedoch auch für Klassendefinitionen verwendet werden (und sollte nicht
static
in C ++ verwendet werden).Alle anonymen Namespaces in derselben Datei werden als der gleiche Namespace behandelt, und alle anonymen Namespaces in verschiedenen Dateien sind unterschiedlich. Ein anonymer Namespace entspricht:
quelle
Der unbenannte Namespace beschränkt den Zugriff von Klassen, Variablen, Funktionen und Objekten auf die Datei, in der er definiert ist. Die Funktionalität für unbenannte Namespaces ähnelt dem
static
Schlüsselwort in C / C ++.static
Das Schlüsselwort beschränkt den Zugriff der globalen Variablen und Funktionen auf die Datei, in der sie definiert sind.Es gibt einen Unterschied zwischen unbenanntem Namespace und
static
Schlüsselwort, aufgrund dessen unbenannter Namespace gegenüber statischen einen Vorteil hat.static
Das Schlüsselwort kann mit Variablen, Funktionen und Objekten verwendet werden, jedoch nicht mit benutzerdefinierten Klassen.Beispielsweise:
Aber,
Dies kann jedoch auch mit einem unbenannten Namespace möglich sein. Beispielsweise,
quelle
Neben den anderen Antworten auf diese Frage kann die Verwendung eines anonymen Namespace auch die Leistung verbessern. Da Symbole im Namespace keine externe Verknüpfung benötigen, kann der Compiler den Code im Namespace aggressiver optimieren. Beispielsweise kann eine Funktion, die mehrmals in einer Schleife aufgerufen wird, ohne Auswirkungen auf die Codegröße eingefügt werden.
Auf meinem System benötigt der folgende Code beispielsweise etwa 70% der Laufzeit, wenn der anonyme Namespace verwendet wird (x86-64 gcc-4.6.3 und -O2; beachten Sie, dass der Compiler durch den zusätzlichen Code in add_val nicht eingeschlossen werden möchte es zweimal).
quelle
-O3
sich selbst verglichen , dann sagten Sie, 3 gegen 4 Sekunden seien "die gleiche Zeit". beides macht keinen Sinn. Ich vermute, die wirkliche Erklärung würde, aber was ist es?Das Beispiel zeigt, dass die Personen in dem Projekt, dem Sie beigetreten sind, anonyme Namespaces nicht verstehen :)
Diese müssen sich nicht in einem anonymen Namespace befinden, da das
const
Objekt bereits eine statische Verknüpfung aufweist und daher möglicherweise nicht mit gleichnamigen Bezeichnern in einer anderen Übersetzungseinheit in Konflikt stehen kann.Und das ist eigentlich eine Pessimisierung:
getState()
hat externe Verknüpfung. Es ist normalerweise besser, eine statische Verknüpfung zu bevorzugen, da dies die Symboltabelle nicht verschmutzt. Es ist besser zu schreibenHier. Ich bin in dieselbe Falle geraten (es gibt Formulierungen im Standard, die darauf hindeuten, dass die Dateistatik zugunsten anonymer Namespaces irgendwie veraltet ist), aber bei der Arbeit in einem großen C ++ - Projekt wie KDE gibt es viele Leute, die Ihren Kopf in die richtige Richtung drehen wieder da :)
quelle
const
Ness zu entfernen später auf Wunsch. Ich bezweifle, dass das OP-Team nichts "versteht"! Außerdem ist das Bit über Funktionen in anonymen Namespaces mit externer Verknüpfung ab C ++ 11 falsch, wie bereits erwähnt. Nach meinem Verständnis haben sie ein Problem mit Vorlagenargumenten behoben, für die zuvor eine externe Verknüpfung erforderlich war, sodass unbenannte Namespaces (die Vorlagenargumente enthalten können) eine interne Verknüpfung aufweisen können.Ein anonymer Namespace stellt die eingeschlossenen Variablen, Funktionen, Klassen usw. nur in dieser Datei zur Verfügung. In Ihrem Beispiel können Sie globale Variablen vermeiden. Es gibt keinen Leistungsunterschied zur Laufzeit oder zur Kompilierungszeit.
Abgesehen von "Soll diese Variable, Funktion, Klasse usw. öffentlich oder privat sein?" Gibt es nicht so viele Vor- oder Nachteile.
quelle