mag ich nicht using namespace std
aber ich bin es auch leid, tippen zu müssen std::
vor jedem cout
, cin
, cerr
und endl
. Also dachte ich daran, ihnen kürzere neue Namen wie diesen zu geben:
// STLWrapper.h
#include <iostream>
#include <string>
extern std::ostream& Cout;
extern std::ostream& Cerr;
extern std::istream& Cin;
extern std::string& Endl;
// STLWrapper.cpp
#include "STLWrapper.h"
std::ostream& Cout = std::cout;
std::ostream& Cerr = std::cerr;
std::istream& Cerr = std::cin;
std::string _EndlStr("\n");
std::string& Endl = _EndlStr;
Das funktioniert. Aber gibt es irgendwelche Probleme in den oben genannten Punkten, die ich übersehe? Gibt es einen besseren Weg, dasselbe zu erreichen?
Alex hat Ihnen eine Antwort gegeben, wie Sie dieses Problem syntaktisch lösen können. Ich möchte jedoch auf zwei weitere Argumente zu diesem Thema hinweisen:
-
Egal, ob Sie eine beschäftigen Direktive verwenden (using namespace std
) oder seine kleinere böse Schwester, a Deklaration verwenden (using std::cout
), kann eine Überlastung zu bösen Überraschungen führen. Es ist nicht viel Aufwand zu tippen std::
verglichen mit eine halbe Nacht mit dem Debuggen verbringen um Ihren Code herauszufinden aufgerufen std::distance()
statt deiner eigenen distance()
funktionieren, nur weil du einen kleinen Fehler gemacht hast und std::distance()
zufällig ist eine bessere Übereinstimmung.
-
Eine Codezeile wird einmal geschriebenaber – je nach Lebensdauer – es wird zehn-, hundert- und manche sogar tausendmal gelesen. So die Zeit, die zum Schreiben einer Codezeile benötigt wird, spielt einfach keine Rolle, wichtig ist nur die Zeit, die zum Lesen und Interpretieren einer Codezeile benötigt wird. Auch wenn es dreimal so lange dauert, eine Zeile mit allem Richtigen zu schreiben std::
an Ort und Stelle, wenn es das Lesen nur 10% schneller macht, ist es immer noch die Mühe wert.
Die wichtige Frage ist also: Ist es einfacher, eine Codezeile mit all dem zu lesen und zu interpretieren? std::
an Ort und Stelle oder ist es schwieriger? Aus einer anderen Antwort:
Hier noch ein Datenpunkt: Vor vielen, vielen Jahren fand ich es auch lästig, alles aus der Standardbibliothek mit voranstellen zu müssen std::
. Dann habe ich in einem Projekt gearbeitet, wo am Anfang entschieden wurde, dass beides using
Direktiven und Deklarationen sind mit Ausnahme von Funktionsbereichen verboten. Erraten Sie, was? Die meisten von uns brauchten nur wenige Wochen, um sich daran zu gewöhnen, das Präfix zu schreiben, und nach ein paar weiteren Wochen waren sich die meisten sogar einig, dass es tatsächlich den Code erstellte besser lesbar. (Dafür gibt es einen Grund: Ob Sie kürzere oder längere Prosa mögen, ist subjektiv, aber die Präfixe verleihen dem Code objektiv Klarheit. Nicht nur der Compiler, sondern auch Sie können leichter erkennen, auf welchen Bezeichner verwiesen wird.)
Innerhalb eines Jahrzehnts wuchs dieses Projekt auf mehrere Millionen Codezeilen an. Da diese Diskussionen immer wieder auftauchen, war ich mal gespannt wie oft der (erlaubte) Funktionsumfang ist using
tatsächlich in dem Projekt verwendet wurde. Ich habe die Quellen dafür durchsucht und nur ein oder zwei Dutzend Stellen gefunden, an denen es verwendet wurde. Das deutet für mich darauf hin, einmal versucht, Entwickler nicht gefunden std::
schmerzhaft genug Verwenden von Direktiven sogar einmal alle 100kLoC auch dort, wo es erlaubt war.
Ich finde es traurig, dass jedes Buch und Tutorial überspringt std::
, weil sich die Leute daran gewöhnen, den Code so zu lesen. Als ich mehrere Jahre lang C++ unterrichtete (nach der oben genannten Erfahrung), sagte ich meinen Schülern, dass ich keine sehen möchte using
Direktive oder Deklaration in ihrem Code. (Die einzige Ausnahme von dieser Regel ist using std::swap
BTW, die Sie benötigen, um zu haben swap(a,b)
Überladungen außerhalb des Namespace aufnehmen std
.) Sobald sie sich daran gewöhnt hatten, machte es ihnen nichts aus und als sie danach gefragt wurden, sagten sie, sie hätten Code ohne das gefunden std::
Präfix verwirrend. Einige fügten sogar hinzu std::
Präfix für Code, den sie aus einem Buch oder Tutorial eingegeben haben, das es nicht hatte.
Fazit: Was ist so schwer am Tippen std::
dass sich alle so darüber aufregen? Mittlerweile mache ich das seit >15 Jahren und vermisse es nicht using
überhaupt.
Warum nicht
using std::cin;
using std::cout;
und so weiter? Dann können Sie in Ihrem Code verwenden cin
, cout
und so weiter, ohne versehentlich den ganzen Rest zu injizieren std
Namespace in Ihren Code.
Dies ist nur in Ordnung, wenn Sie ein Ein-Mann-Unternehmen sind und niemand sonst den Code jemals lesen wird. Verknüpfungen wie diese dienen nur dazu, den Code zu verschleiern, und sind selten eine gute Idee für ein Entwicklerteam.
– Martin York
21. Mai 2010 um 10:27 Uhr
Martin: Punkt notiert. Ja, dies ist möglicherweise keine gute Idee, wenn Code mit anderen Personen verwendet wird.
– Ashwin Nanjappa
21. Mai 2010 um 10:29 Uhr
Das
std::string& Endl
hier definiert hat eine andere Funktionalität alsstd::endl
die versucht, den Puffer zu leeren.– Noch ein Parker
1. April 2015 um 16:38 Uhr