Während ich den Google-Standard lese, können Sie die using namespace foo;
Direktive nirgendwo verwenden. Diese Anweisung fügt alle im Namespace deklarierten Elemente ein und ist eine häufige Ursache für Kollisionen und unerwartetes Verhalten. Andere haben eine sehr verbreitete Methode zitiert: Sie haben irgendwo Ihre eigene Max- oder Min-Methode und diese kollidiert in einer src-Datei, in der jemand einen Header mit Ihrer Methode enthält und dann sagtusing namespace std;
An bestimmten Stellen ist es gestattet, eine Verwendungserklärung zu haben, die von der Form ist using ::foo::bar;
Die Leute setzen gerne Direktiven in ihren Code ein, weil dies viel Tipparbeit spart, aber mit Risiken verbunden ist. Wenn Sie eine Datei mit vielen cout-Anweisungen haben, kann ich verstehen, dass Sie std :: cout nicht hundertmal eingeben müssen, aber Sie können einfach sagen, dass Sie :: std :: cout verwenden. Ich behandle diese wie Variablendeklarationen: Bereich sie, wo sie gebraucht werden. Wenn eine Funktion in einer 10er-Datei eine Ausgabe schreiben muss, deklarieren Sie den cout-Weg nicht oben, sondern fügen Sie ihn in die Funktion ein, die die eigentliche Ausgabe ausführt.
#include <ostream>
//using namespace std; // NO!
//using ::std::cout; // less bad than using namespace, but I prefer to scope it
int main(int argc, char** argv)
{
int rc = do_some_stuff(argc, argv);
using ::std::endl;
if (rc) { // print the success report
using ::std::cout;
cout << "The test run completed. The return code was " << rc << '.' << endl;
} else {
using ::std::cerr;
cerr << "Unable to complete the test run." << endl;
}
return 0 == rc;
}
Das ist ein bisschen extrem, nur ein paar Zeilen geben aus, aber Sie haben die Idee.
Eine andere Möglichkeit ist Alias oder typedef, um die Eingabe zu minimieren. Ich finde std :: what nicht so schlimm, aber wir haben eine riesige Menge an Quellcode mit mehreren Dutzend Modulen und manchmal müssen wir Code wie schreiben console_gui::command_window::append("text")
. Das wird nach einer Weile langweilig und verursacht viele lange Schlangen. Ich bin alles für so etwas wie
typedef console_gui::command_window cw;
cw::append("text");
solange die Aliase in einem lokalen Bereich erstellt werden und genügend Kontext vorhanden ist, um den Code lesbar zu machen.
std::endl
für das explizite Flush onstdout
/stderr
ist normalerweise überflüssig, diese Streams sind ohnehin anstdout
/ gebundenstderr
. Es verlangsamt sogar die Dinge ein bisschen.Dies liegt daran, dass: 1) es den gesamten Zweck von Namespaces zunichte macht, nämlich die Namenskollision zu verringern; 2) Er stellt dem globalen Namespace den gesamten Namespace zur Verfügung, der mit der using-Direktive angegeben wurde.
Wenn Sie beispielsweise Ihre eigene max () -Funktion einfügen und definieren, kollidiert diese mit std :: max ().
http://en.cppreference.com/w/cpp/algorithm/max
Die Voreinstellung ist std :: member_you_wish_to_use, da explizit angegeben wird, welcher Namespace verwendet werden soll.
quelle
std::max()
mit dem Namensraumpräfix verwenden sollte. Oder irre ich mich?using
Dies bedeutet nur, dass Sie mit Direktiven vorsichtig sein sollten, da dies in diesem Fall Ihre max () - Funktion unterbrechen würde, wenn Sie eine definiert und <algorithm> eingeschlossen hätten. Dies ist ein einfacher Fall, aber Sie wissen nie, was Sie brechen könnten. Sie müssten die gesamte Bibliothek kennen, um sicherzugehen, dass Sie sie nicht beschädigt haben, aber Sie können nicht wissen, ob Ihr Code in Zukunft beschädigt werden würde (dh Namenskollisionen).Zitieren Sie den von Ihnen angegebenen Link:
Der Google-Stil verbietet das Importieren von Namespaces im globalen Kontext, erlaubt dies jedoch in lokalen.
Überall dort, wo die Deklaration nur einen begrenzten und gut sichtbaren Teil des Codes betrifft, ist sie vollkommen akzeptabel.
Wenn Sie den globalen Kontext verschmutzen, ist nicht verwandter Code betroffen (implizit mithilfe Ihres Headers). Nichts passiert, wenn Sie dies im lokalen Kontext tun.
quelle
Du machtest. Die Nichtempfehlung gilt nur für die
using namespace
Richtlinie (die gemeinhin alsabusing namespace
nicht ganz humorvoll bezeichnet wird). Es wird dringend empfohlen, den vollqualifizierten Namen einer Funktion oder eines Objekts zu verwenden, zstd::cout
.quelle
Obwohl die Frage bereits nützliche Antworten hat, scheint ein Detail zu kurz zu kommen.
Die meisten Programmierer sind zunächst ein wenig verwirrt mit dem
using
Schlüsselwort und dennamespace
Verwendungsbeschreibungen, auch wenn sie versuchen, es durch Nachschlagen der Referenz zu lernen, weil Deklaration und Direktive etwas äquivalent sind. Beide sind relativ abstrakte lange Wörter, die mit d beginnen .Auf Bezeichner in Namespaces kann zugegriffen werden, indem der Namespace explizit benannt wird:
Das können viel mehr Schlüssel sein, die eingegeben werden müssen. Es kann aber auch die Bedeutung Ihres Codes verringern, wenn die meisten Bezeichner auf die gleiche Weise vorangestellt werden. Das
using
Schlüsselwort hilft, diese Namespace-Nachteile zu vermeiden. Da esusing
auf Compilerebene funktioniert (es ist kein Makro), wirkt es sich auf den gesamten Gültigkeitsbereich aus, in dem es verwendet wird. Aus diesem Grund beschränkt der Google-Stil seine Verwendung auf genau definierte Gültigkeitsbereiche, z. B. Klassen in Headerdateien oder Funktionen in CPP-Dateien.... Natürlich gibt es einen Unterschied zwischen der Deklaration
und mit Direktive
Bei Verwendung in großen Bereichen führt Letzteres zu viel mehr Verwirrung.
quelle
Bitte schön:
Durch diese Schreibweise vermeiden wir fehleranfälliges ADL sowie die Verwendung von Direktiven und Deklarationen.
Dies soll eine sarkastische Antwort sein. :-D
Ich bin mit Herb Sutter über Google in diesem Fall. Aus C ++ - Codierungsstandards:
Sie können von potenziellen Namespace-Konflikten besessen sein, die sich wahrscheinlich nie manifestieren werden und in einem solchen astronomisch seltenen Ereignis wahrscheinlich nicht schwer zu beheben sind, indem Sie
using
Anweisungen sorgfältig vermeiden und jede einzelne von Ihnen verwendete Funktion (bis auf die Operatoren) explizit mitusing
Deklarationen oder angeben mach einfach weiter und fang anusing namespace std
. Letzteres empfehle ich aus Sicht der Produktivität.Das Gegenteil, wenn Sie mich fragen, und ich glaube, Sutter oben stimmt zu.
Jetzt, im Laufe meiner Karriere, habe ich insgesamt 3 Namespace-Konflikte als direkte Folge von
using
Direktiven in Codebasen festgestellt, die sich über Dutzende von Millionen von LOC erstrecken. In allen drei Fällen befanden sie sich jedoch in Quelldateien, die mehr als 50.000 Zeilen Legacy-Code umfassten, ursprünglich in C geschrieben und dann in C ++ bastardisiert wurden und eine umfangreiche eklektische Liste unterschiedlicher Funktionen, einschließlich Header aus einem Dutzend verschiedener Bibliotheken, aufwiesen eine epische Liste von#includes
, die sich über eine Seite erstreckt. Trotz des epischen Durcheinanders waren sie nicht allzu schwierig zu beheben, da sie unter OSX (dem Betriebssystem, auf dem der Code nicht erstellt werden konnte) Buildfehler und keine Laufzeitfehler verursachten. Ordne deinen Code nicht so albtraumhaft an, und es sollte dir gut gehen.Vermeiden Sie jedoch sowohl
using
Direktiven als auch Deklarationen in Header-Dateien. Das ist einfach nur zurückgeblieben. Aber für Quelldateien und insbesondere für solche, bei denen keine ganze Seite mit#include
Direktiven gefüllt ist , würde ich sagen, dass Sie nicht ins Schwitzen kommen, wenn Sie nicht für Google arbeiten.quelle