Ich bin mit allem einverstanden Greg schrieb aber ich möchte noch etwas hinzufügen: Es kann sogar noch schlimmer kommen, als Greg gesagt hat!
Die Bibliothek Foo 2.0 könnte eine Funktion einführen, Quux()
die eindeutig besser zu einigen Ihrer Aufrufe an Quux()
als die bar::Quux()
Ihr Code wird seit Jahren aufgerufen. Dann wird Ihr Code lässt sich noch kompilieren aber ruft er stillschweigend die falsche Funktion auf und tut Gott-weiß-was. Schlimmer kann es nicht mehr werden.
Beachten Sie, dass die std
Namespace hat eine Vielzahl von Bezeichnern, von denen viele sehr gemeinsame (denken Sie an list
, sort
, string
, iterator
usw.), die mit großer Wahrscheinlichkeit auch in anderem Code vorkommen.
Wenn Sie dies für unwahrscheinlich halten: Es gab eine gestellte Frage hier auf Stack Overflow, wo so ziemlich genau das passiert ist (falsche Funktion aufgerufen aufgrund von ausgelassenen std::
Präfix), etwa ein halbes Jahr nachdem ich diese Antwort gegeben habe. Ici ist ein weiteres, jüngeres Beispiel für eine solche Frage. Dies ist also ein echtes Problem.
Hier ist ein weiterer Datenpunkt: Vor vielen, vielen Jahren habe ich es auch als lästig empfunden, allem aus der Standardbibliothek das Präfix std::
. Dann arbeitete ich an einem Projekt, bei dem zu Beginn beschlossen wurde, dass beide using
Direktiven und Deklarationen sind verboten, außer für Funktionsbereiche. Und nun raten Sie mal! Die meisten von uns brauchten nur wenige Wochen, um sich an die Schreibweise des Präfixes zu gewöhnen, und nach ein paar weiteren Wochen waren sich die meisten von uns sogar einig, dass der Code dadurch tatsächlich besser wurde besser lesbar . Dafür gibt es einen Grund: Ob man kürzere oder längere Prosa mag, ist subjektiv, aber die Präfixe tragen objektiv zur Klarheit des Codes bei. Nicht nur für den Compiler, sondern auch für Sie ist es einfacher zu erkennen, auf welchen Bezeichner er sich bezieht.
Innerhalb eines Jahrzehnts wuchs dieses Projekt auf mehrere Millionen Codezeilen an. Da diese Diskussionen immer wieder auftauchen, war ich einmal neugierig, wie oft der (erlaubte) Funktionsumfang using
tatsächlich in dem Projekt verwendet wurde. Ich habe die Quellen danach durchsucht und nur ein oder zwei Dutzend Stellen gefunden, an denen es verwendet wurde. Für mich ist das ein Hinweis darauf, dass Entwickler, wenn sie es einmal ausprobiert haben, nicht finden std::
schmerzhaft genug, um die Verwendung von Richtlinien auch nur alle 100 kLoC zuzulassen, selbst dort, wo die Verwendung erlaubt war.
Unterm Strich: Alles explizit voranzustellen schadet nicht, ist sehr gewöhnungsbedürftig und hat objektive Vorteile. Insbesondere macht es den Code für den Compiler und den menschlichen Leser leichter zu interpretieren - und das sollte wohl das Hauptziel beim Schreiben von Code sein.
710 Stimmen
Vergessen Sie nicht, was Sie tun können: "using std::cout;", was bedeutet, dass Sie nicht std::cout eingeben müssen, aber nicht gleichzeitig den gesamten std-Namensraum mit einbeziehen.
115 Stimmen
Es ist besonders schlecht, 'using namespace std' in Headerdateien im Dateisystem zu verwenden. Die Verwendung in Quelldateien (*.cpp) im Dateisystem nach allen Includes ist nicht ganz so schlimm, da ihre Wirkung auf eine einzige Übersetzungseinheit beschränkt ist. Noch weniger problematisch ist die Verwendung innerhalb von Funktionen oder Klassen, da die Wirkung auf den Funktions- oder Klassenbereich beschränkt ist.
15 Stimmen
Ich würde davon abraten, die using-Direktive zu verwenden, aber für bestimmte Namespaces wie
std::literals::chrono_literals
,Poco::Data:Keywords
,Poco::Units
und andere Dinge, die mit Literalen oder Lesbarkeitstricks zu tun haben. Immer dann, wenn es in Header- oder Implementierungsdateien steht. In einem Funktionsbereich mag es in Ordnung sein, aber abgesehen von Literalen und anderen Dingen ist es nicht nützlich.1 Stimmen
@sh- Warum meinen Sie, dass es "besonders schlecht" ist, "using namespace std" zu verwenden?
22 Stimmen
@Jon: Es hat nichts mit dem Namespace std im Besonderen zu tun. Meine Betonung lag auf "in Dateigröße in Header-Dateien". Um es als Ratschlag zu formulieren: Verwenden Sie "using namespace" (std oder andere) nicht im Dateisystem von Header-Dateien. Es ist OK, es in Implementierungsdateien zu verwenden. Entschuldigung für die Zweideutigkeit.
11 Stimmen
Es wird nur in Kopfzeilen als schlechte Praxis angesehen. In Quelldateien, die nicht anderweitig eingebunden sind (z. B. cpp-Dateien), ist es in Ordnung. Siehe @mattnewport 's Antwort unten. stackoverflow.com/a/26722134/125997
3 Stimmen
Ich habe den anderen keine Antwort hinzuzufügen, aber ich benutze:
using [namespace]::[identifier];
im lokalen Bereich von relativ einfachen Quelldateien. Wenn ich zum Beispiel einen Header habe, der häufig die voll qualifizierte:std::size_t
Typ, werde ich normalerweise vorangestellt:using std::size_t;
zur Umsetzung. Dies vereinfacht Lesen den Code und wirkt sich nur auf den lokalen Bereich aus - das heißt:using std::[identifier];
verwendet die Prinzip der geringsten Überraschung . Es gibt zu viele Bezeichner in derstd
Namespace, den man im Auge behalten muss. Spätere C++-Revisionen können Bezeichner hinzufügen, die mit Ihren eigenen kollidieren!0 Stimmen
Das macht Ihren Code einfacher.
0 Stimmen
>Warum ist das so? Weil die Leute in manchen Bereichen nichts wirklich zu tun haben und anfangen, über Dinge zu debattieren, die nicht wichtig sind. In der Sprache C++ können Sie jede Strategie verwenden, aber bitte verstehen Sie die using-directive und die using-declaration.