2016-05-12 9 views
6

halte ich Code wie dies überall in meiner Firma zu sehen:Unnötige Verwendung von unbenannte Namensräume C++

namespace { 

const MAX_LIMIT = 50; 
const std::string TOKEN = "Token"; 

} 

Ich bin verwirrt, wie, warum Sie einen anonymen Namespace müssen hier. Auf der einen Seite möchten Sie eine lokale Übersetzungseinheit für MAX_LIMIT AND TOKEN. Aber das ist schon ohne den anonymen Namensraum aufgrund der const erreicht. static const und einfach const erreichen beide lokale Übersetzungseinheit.

Auf der anderen Seite haben Sie keine Namenskonflikte, wenn Sie irgendwo in Ihrer Datei eine Variable mit dem gleichen Namen haben.

int foo() 
{ 
std::string TOKEN = "MyToken"; // Clash! ::TOKEN vs TOKEN can be used. 
} 

Das würde den anonymen Namespace rechtfertigen. Aber wie oft brauchen Sie einen Variablennamen in Ihrer Funktion, der bereits von einer außerhalb Ihrer Funktion deklarierten const Variable belegt ist? Meine Antwort ist niemals. In der Praxis wird also der unbenannte Namensraum nicht benötigt. Irgendwelche Hinweise?

+3

Ich würde sagen Konsistenz: diese 'const' Regel gilt nur für ganzzahlige Typen. – Quentin

+6

@Quentin Huh? 'const' im Namespace-Bereich hat eine interne Verknüpfung, sofern nicht 'extern' markiert ist, für alle Typen –

+0

@ M.M My bad! Ich weiß nicht, woher ich das zurückgerufen habe, aber ich war mir auch ziemlich sicher. Zumindest bin ich nicht allein: D – Quentin

Antwort

3

In diesem speziellen Fall ist der Namespace in der Tat redundant, da die Namespace-Variablen des const-Names in der Tat intern standardmäßig verknüpft sind.

Betrachten Sie die Möglichkeit, den Code später zu ändern. Vielleicht sollte eine der Variablen doch nicht const sein. Wenn Sie es nicht-const machen, ändert sich auch die Standardverknüpfung. Der anonyme Namespace würde die interne Verknüpfung auch nach einer solchen Änderung beibehalten. Mit anderen Worten trennt der Anon-Namespace die Bedenken über die Konstanz und die Verknüpfung. Ob das gut ist, hängt vom Kontext ab.

Beachten Sie, dass das Gleiche mit dem Schlüsselwort static erreicht werden kann. Da dies genau die gleiche Wirkung wie der Anon-Namensraum hat, ist die Auswahl hauptsächlich ästhetisch und daher auf der Meinung der Nutzer basiert.

Ein Argument für die Verwendung anon Namespaces anstelle von static könnte Konsistenz sein. Sie können keine Typen mit interner Verknüpfung mit static definieren. Da einige interne Symbole (Typen) nicht außerhalb eines anonymen Namespace definiert werden können, können Sie eine Konvention definieren, um alle internen Symbole in einem anonymen Namespace zu definieren. Natürlich wäre eine solche Übereinkunft - wie Konventionen typischerweise - eine Frage des Geschmacks.

Ihr zweites Gegenargument scheint gegen einen Unterschied zu argumentieren, der nicht existiert. Der anonyme Namespace macht keinen Unterschied zum Ausblenden von Namen im Funktionsumfang.

+0

@LightnessRacesinOrbit Ich überlegte, ob es eine Möglichkeit gab, eine dritte Ebene zu der Opinception hinzuzufügen, aber ich konnte nicht tief genug. – user2079303

+0

Sie konnte nicht tief genug werden ... _ Ihrer Meinung nach_ –

5

Die namespace ist redundant, wie Sie erklären. Sie könnten die namespace { und die passende } entfernen.

Ein Unterschied ist, dass Sie verschiedene Namen ::TOKEN und unnamed_namespace::TOKEN haben könnten. Aber das bringt wahrscheinlich nur Verwirrung und es wäre besser, einen Kompilierungsfehler zu bekommen.

Nicht sicher, worum es in der zweiten Hälfte Ihres Posts geht, lokale Variable TOKEN shadows ::TOKEN und unnamed_namespace::TOKEN. Die Änderung würde also keinen Unterschied machen.

0

Wohl verbessert es Klarheit. Ein anonymer Namespace sagt viel deutlicher "dieser Code ist Implementierungsdetail für diese Kompilierungseinheit allein, nicht als Teil der Schnittstelle der Einheit beabsichtigt". Da Sie auf diese Weise anonyme Namespaces für lokale Klassen oder Strukturen verwenden müssen (keine andere Möglichkeit, sie zu lokalisieren), ist es sinnvoll, alle Ihre lokalen Konstrukte auf diese Weise zu kapseln.