Umfang der Verwendung der Deklaration in einem Namespace
Ist es sicher (und korrekt) in einer C++ - header-Datei verwenden Sie die using-Deklaration in einen namespace wie folgt:
#include <boost/numeric/ublas/vector.hpp>
namespace MyNamespace {
using boost::numeric::ublas::vector;
vector MyFunc(vector in);
}
I. e. ist die "Verwendung von boost::numeric::ublas::vector" ordnungsgemäß innerhalb der MyNamespace block, oder wird das verschmutzen der namespace eine Datei, die diese header?
Kommentar zu dem Problem - Öffnen
Was genau meinst du mit "den namespace eine Datei"? Es wird "verschmutzen" die
MyNamespace
- namespace in einer übersetzung Einheit, die vom Punkt der Deklaration der mit der Erklärung ab. für ein einzelnes symbol... warum gehst du nicht mit einem
typedef
? @Matthieu: Da
boost::numeric::ublas::vector
ist eine Vorlage. Ich war bisher mit dem standard "Vorlage " typedef" Abhilfe (stackoverflow.com/questions/26151/...), sondern wollte, um die Dinge zu vereinfachen ein bit. argh! In C++0x, Sie haben Möglichkeiten, um alias-templates... allerdings müssen Sie deklarieren alle Argumente, die Sie verwenden möchten, aber sonst sind Sie Art stecken, denke ich.
InformationsquelleAutor der Frage Brett Ryland | 2011-05-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, es ist nicht sicher - es wird nicht verschmutzen einem anderen namespace, aber es ist gefährlich für andere Gründe:
Einen
using
Richtlinie importieren Sie etwas , die aktuell sichtbar ist durch den Namen, den Sie angeben, zu der namespace, in dem Sie es verwenden. Während Ihrusing
nur sichtbar für Benutzer vonMyNamespace
andere Dinge von "außen" sichtbar werden zu Ihremusing
Erklärung.So, wie ist das gefährlich, wenn verwendet, in einer Kopfzeile? Weil es import-Dinge, die sichtbar sind an dem Punkt der Erklärung, das genaue Verhalten hängt von der Reihenfolge der Kopfzeilen, die Sie vor der Deklaration (und vielleicht andere Dinge, die sichtbar von
boost::numeric::ublas::vector
). Da kann man nicht wirklich Steuern, welche Header enthalten sind, bevor Sie eine überschrift (noch sollten Sie sein! Header sollte autark sein!), dies kann dazu führen, dass sehr seltsame Probleme, wo Ihr die Funktion findet sich der eine Sache, die in einer compilation-unit und eine weitere in der nächsten.Als Faustregel gilt, dass
using
Erklärungen sollten nur verwendet werden, nach alle gehören in eine .cpp-Datei. Es gibt auch einen Artikel über genau dieses Thema in dem Buch "C++ Coding Standards" von Sutter und Alexandrescu (Item 59). Hier ein Zitat: "Aber hier ist die gemeinsame Falle: Viele Menschen denken, dass die Verwendung von Erklärungen, die auf namespace-Ebene (...) sicher sind. Sie sind es nicht. Sie sind mindestens so gefährlich, und ein subtiler und heimtückischer Weise."Selbst wenn es unwahrscheinlich ist, dass der name, den Sie sind
using
existiert nicht irgendwo anders (wie wohl hier der Fall), können die Dinge hässlich werden: In einem header, alle Erklärungen werden sollte voll qualifiziert. Dies ist Schmerz, aber sonst seltsame Dinge passieren können.Edit: Sehen Die Migration zu Namespaces für die Beispiele und das problem beschrieben, in die Tiefe.
InformationsquelleAutor der Antwort ltjax
Einer using-Deklaration ist, wie der name schon sagt, eine Erklärung. Alle Angaben bezieht sich auf den umschließenden block (7.2), in diesem Fall der namespace
MyNamespace
. Es wird nicht sichtbar sein, außerhalb dieses namespace.InformationsquelleAutor der Antwort Björn Pollex
Ist es sicher, aber es wird verschmutzen den namespace MyNamespace. Also, eine Datei enthalten ist, wird die überschrift über Funktionen/Klassen in den MyNamespace.
InformationsquelleAutor der Antwort BЈовић
Es verschmutzt nicht andere namespaces, aber es wird sicherlich belasten den namespace MyNamespace.
InformationsquelleAutor der Antwort Puppy
Zusammenfassen, keine, using-Deklarationen in einer header sind nicht ok, auch innerhalb eines Namensraums, aus 2 Gründen. Weitere, using-Deklarationen innerhalb eines namespace in einem nicht-header sind fehleranfällig oder sinnlos (siehe Ende). Using-Deklarationen in einer header sind nicht ok, weil:
In deinem Beispiel bedeutet dies:
MyNamespace
,vector
jetzt lösen, zuboost::numeric::ublas::vector
, für alle Dateien, die mit diesem header: es "verpestet" dieMyNamespace
namespace.boost::numeric::ublas::vector
Erklärungen importiert werden, hängt davon ab, was Erklärungen erscheinen vor diese using-Deklaration, die abhängig von der Bestellung enthält in der Datei, die diese header, und alle seine umfasst (richtig, die Reihenfolge der Deklarationen in der übersetzungseinheit nach der Vorverarbeitung).Pro Ihrem Kommentar Kann 30 '11 at 11:51 Sie wirklich wollen, Verhalten 1, aber das funktioniert nicht, wegen problem 2. Sie können das gewünschte Verhalten durch einen separaten header, der enthalten ist, nachdem alle anderen (und voll qualifizierte Namen in anderen Headern). Dies ist jedoch zerbrechlich und daher abgeraten, vorzugsweise reserviert wird nur bei der Umstellung auf namespaces:
Sehen GotW #53: Migration zu Namespaces für details, die dieses Problem umgehen und den Rat: "Namespace using-Deklarationen sollte nicht in header-Dateien".
Ist es möglich, zu vermeiden, problem 1 durch hinzufügen eines Unbenannte Namespaces, um die using-Deklaration (um zu verhindern, dass diese Namen aus sichtbar ist) und dann noch einen außerhalb der Unbenannte namespace (um den gewünschten Namen sich sichtbar), aber immer noch leidet unter problem 2 und uglifies der Kopfzeile:
Aufgrund dieser Probleme, sollten Sie nur mit-Deklarationen in nicht-header - (.cc/.cpp-Dateien): dies hat keine Auswirkungen auf andere Dateien, so problem 1 ist vermieden; und alle Header enthalten, wurden so problem 2 ist, vermieden. In diesem Fall ist es eine Frage des Geschmacks, ob man Sie in einem namespace oder nicht, da Sie keine Auswirkungen auf andere Dateien, ist es am sichersten, verwenden Sie immer vollständig qualifizierte Namen in der using-Deklaration selbst (absolute, beginnend mit
::
).Einfachsten ist es, alle using-Deklarationen am Beginn der Datei, nach der das beinhaltet, ist aber außerhalb des namespaces: diese ist sicher, eindeutig, leicht zu Lesen, und erlaubt, dass die Namen werden in der gesamten Datei. Einige gemeinsame Abweichungen:
Using-Deklaration mit einem relativen Namen innerhalb eines (benannten) namespace: fehleranfällig. Dies ist präziser und fügt einige Klarheit (ähnliche Namen in den Namensraum auf die Sie sich beziehen), sondern ist potentiell mehrdeutig (wie auch mit relativen Pfaden), und ist sicherer zu vermeiden:
Using-Deklaration mit einem absoluten Namen in einem benannten namespace: sinnlos. Dies führt nur den Namen in den Namensraum, aber man sollte Sie nicht kümmern, da sollte man sich nicht darunter .cc/.cpp Datei:
Using-Deklaration in einen unbenannten Namensraum: sinnlos, etwas gefährlich. Zum Beispiel, wenn Sie eine Funktion in einen unbenannten Namensraum, sagen, dass eine Implementierung detail, dann kann man sich eine mit-Erklärung für seine Wiederkehr geben-oder param-Typen. Dieser stellt die Namen in diesem namespace (also nicht referenziert werden aus anderen Dateien), aber wieder, Sie sollten nicht egal, denn Sie sollte nicht darunter die .cc/.cpp Datei (Unbenannte Namensräume sind vor allem für vermeiden name-clashes zur link-Zeit, die nicht hier gilt: es ist nur eine compile-time-alias). Schlimmer noch, es führt Mehrdeutigkeit, wenn dieser name bereits existiert!
InformationsquelleAutor der Antwort Nils von Barth