Was genau bewirkt das "using namespace std" in einem C++-Programm?

3 Antworten

Kurze Antwort:

Trotz des Include musst Du ohne "using..." schreiben:

std::cin
std::cout

Mit using kannst du darin std:: weglassen. Es ist aber kein guter Stil, "using namespace" auf Dateiebene (also am Anfang einer cpp-Datei) zu verwenden. Wenn, sollte es innerhalb der Methode stehen, die das benötigt. Für std ist das aber nie notwendig, es gibt aber andere Bibliotheken mit stark verschachtelten Namespaces (z.B. boost), da bietet sich das schon an.

Namespaces dienen der logischen Segmentierung, sodaß unter anderem auch Namenskolliisionen minimiert werden. Using namespace <name>; bricht diese Segmentierung auf, indem es den Namespace <name> in den globalen Namespace hinüberzieht.


KarlRanseierIII  03.03.2019, 15:04

Ich muß das in sofern korrigierend ergänzen, als daß ich natürlich auch in einen neuen Namespace (um)ziehen kann, es muß nicht immer der globale NS sein.

Allerdings ist das (leider) eine der häufigsten Verwendungen.

0
Mikkey  03.03.2019, 15:56
@KarlRanseierIII

Ich hoffe Du bist mir nicht böse, aber ein "Umzug" ist e eigentlich nicht.

Die Klausel ermöglicht, die Definitionen des angesprochenen Namespace im aktuellen Scope ohne die eigentlich erforderliche Namespace-Qualifizierung zu verwenden.

"using namespace" auf Quelldateiebene ist eigentlich bäh, erst recht in Headern. Ich halte die aber auf Methodenebene für sehr sinnvoll.

1
KarlRanseierIII  03.03.2019, 16:04
@Mikkey

Man kann sich natürlich vortrefflich streiten, wie man es formal am besten beschreibt. Letzlich bricht man die Kapselung auf und zieht es in die aktuelle Scope (nicht zwingend globale Scope) da hast Du natürlich recht.

Das war auch eher aus der Frustration heraus, daß auch in Lehrmaterial häufig direkt unter den #include-s ein using namespace gemacht wird und das ist in den seltensten Fällen das, was man möchte. (Ich müßte jetzt allerdings selbst erst im Standard schauen, ob durch die 'translation unit' noch einmal gescoped wird, oder ob es dann wirklich direkt in :: landet.)

Wie dem auch sei, neben Methoden kann es auch in einer Unit sinnvoll sein, wenn ich zum Beispiel einen eigenen Namespace für meine Bibliothek habe und den std Namespace direkt reinziehen möchte, weil ich genau weiß, daß keine Kollisionen zu erwarten sind.

1
Mikkey  03.03.2019, 16:12
@KarlRanseierIII

Naja, es sind ja nicht nur die Kollisionen. Auch ein späterer Leser des Codes hat es einfacher, wenn er "std::thread" vorfindet, statt einfach nur "thread".

Außerdem - bei einer neueren STL-Version müsstest Du Deinen Code überprüfen, ob deren neue Elemente mit Deinem alten Code kollidieren. Es gibt da lustige und schwer zu findende Fehler ;-)

1
KarlRanseierIII  03.03.2019, 16:15
@Mikkey

Stimmt, ich votiere ohnehin dafür es lieber voll zu qualifizieren, wenn es nicht gerade (wie bei Deinem Beispiel mit Boost) so tiefe Namernraumshierachien sind, daß einem die Finger abbrechen.

Und dann eben im Idealfall auch so, daß man direkt sieht, was in welche Scope geholt wurde.

1
Mikkey  03.03.2019, 16:25
@KarlRanseierIII

Ich finde es schade, dass es bei Namespaces nicht ebenso geht wie bei Typen:

using siTemperature = boost::units::si::temperature;

geht,

using namespace si = boost::units::si;

geht aber leider nicht. Dann wäre der Code besser lesbar, trotzdem ist die "fremde" Herkunft sofort erkennbar.

1
KarlRanseierIII  03.03.2019, 16:33
@Mikkey

Sollte das nicht mit der Definition eines eigenen Namespace machbar sein?

namespace si{
  using namespace boost::units::si;
}

si::<whatever>

Oder übersehe ich gerade etwas?

1
KarlRanseierIII  03.03.2019, 16:39
@KarlRanseierIII

Und aus

using namespace si = boost::units::si;

Mache ein:

namespace si = boost::units::si;

Und schon hast Du ein Aliasing gemacht, sodaß Du über si:: innerhalb der Scope den vollqualifizierten Namespace ansprechen kannst ;-).

1
Mikkey  03.03.2019, 17:04
@KarlRanseierIII

Ist eine Idee, muss ich bei nächster Gelegenheit ausprobieren - im Moment habe ich nach dem Qt 12.1 Installationsversuch gar keine C++ Umgebung.

0
Mikkey  03.03.2019, 19:56
@KarlRanseierIII

Tatsächlich, es funktioniert beides. Die erste Variante finde ich eigentlich ein starkes Stück, aber ist egal, man muss ohnehin aufpassen, was man macht.

0
KarlRanseierIII  03.03.2019, 20:10
@Mikkey

Letztlich liegt es eben an den schmutzigen Details der Namespaces, die im Endeffekt ein Lookupo-Tree sind (wenn Du es Dir vorstellen möchtest), die dann in verschiedenen Scopes gebunden werden.

Eventuell wird jetzt auch verständlicher, warum ich das salopp als 'umziehen' formuliert hatte.

0