Nutzung von using namespace std;



  • Hallo,
    nutzt ihr oft "using namespace std;" um sich das std::string z.B. ständig zu sparen?



  • @CppConst nein



  • Gibt es dafür einen Grund? Falls jetzt die Antwort "ja" kommt, würde ich gerne wissen welchen.



  • Wären es nur cin, cout, string und vector, würde ich das sofort benutzen. Aber das using importiert ja gleich alle Namen in den aktuellen Namespace.

    Der einzige Vorteil ist, dass man ein paar Tastenanschläge spart - und wenn man Code auf einer Slide zeigt, ist das auch platzsparend. Daher: für Slides und kurze Demos ja.

    Aber ansonsten hat man eigentlich nur Nachteile. Man sieht nicht mehr, ob eine Funktion direkt aus der STL stammt und man könnte Namenskonflikte mit gleichnamigen eigenenen Funktionen bekommen. Vielleicht noch nicht mal im aktuellen Programm, aber in einem zukünftigen Programm.

    Und in Headers ist das using sowieso dämlich, weil es gleich alle Dateien beeinflusst, die den Header importieren. Da steht es also völlig außer Frage.

    In kleinen Mini- oder Demoprogrammen kann man das in der cpp-Datei schon mal benutzen. Generell überwiegen die Nachteile aber, je größer das Programm wird. Und ja, vielleicht hat jemand sogar eine eigene string-Klasse geschrieben, weil std::string nicht gut genug war. Und dann ist die Konfusion hoch, wenn man das using namespace benutzt.



  • Toll, danke für die Antwort. Das hilft mir wenigstens enorm weiter.



  • Bei std::swap ist es notwendig, dass man für das korrekte Funktionieren es in den aktuellen Namensraum aufnimmt using std::swap ist dafür aber ausreichend.



  • Danke für den Tipp



  • @john-0 sagte in Nutzung von using namespace std;:

    für das korrekte Funktionieren

    für das ggf performantere Funktionieren



  • Es geht nicht nur um Performance, sondern auch um das Thema UB. Ich habe die aktuelle Norm noch nicht durchgelesen, aber in C++17 bestand das Problem, dass die Richtlinie für die Containerentwicklung (d.h. alle Container in der Norm sind betroffen) vorsehen, dass swap O(1) ist, und das für viele Allokatoren nicht erfüllt werden kann. Man muss bei swap std::allocator_traits<Allocator<T>>::is_always_equal und std::allocator_traits<Allocator<T>>::propagate_on_container_swap berücksichtigen, ist nicht mindestens eines der beiden std::true_type, dann liefert std::swap UB.



  • Mmh, verstehe ich nicht. Es geht doch darum die Spezialisierung zu finden. Wird diese nicht gefunden, wird "normal" geswappt. Warum sollte das UB sein, selbst wenn es O(n^99) wäre?



  • Nö, dank Intellisense und Snippets spart man ja nicht mal mehr Tipparbeit. Also lieber eindeutig bleiben und Probleme vermeiden.



  • @Jockelx sagte in Nutzung von using namespace std;:

    Mmh, verstehe ich nicht. Es geht doch darum die Spezialisierung zu finden. Wird diese nicht gefunden, wird "normal" geswappt. Warum sollte das UB sein, selbst wenn es O(n^99) wäre?

    Wenn man immer std::swap schreibt, wird die Spezialisierung nicht gefunden und std::swap genutzt. std::swap hat aber das Problem, dass es einige zusätzliche Annahmen macht, die seit C++11 nicht mehr generell erfüllt sind. Ich habe einen eigenen Beitrag dazu eingefügt, damit dürfte nachvollziehbar sein was ich meine.


  • Banned

    Danke für den Tipp auch!



  • @john-0 sagte in Nutzung von using namespace std;

    Wenn man immer std::swap schreibt, wird die Spezialisierung nicht gefunden und std::swap genutzt. std::swap hat aber das Problem, dass es einige zusätzliche Annahmen macht, die seit C++11 nicht mehr generell erfüllt sind. Ich habe einen eigenen Beitrag dazu eingefügt, damit dürfte nachvollziehbar sein was ich meine.

    Nicht, wenn man seine Spezialisierung im Namespace std implementiert:

    struct MyStruct
    {
    };
    
    namespace std
    {
        template<>
        void swap( MyStruct& lhs, MyStruct& rhs )
        {
           ...
        }
    }
    


  • @DocShoe sagte in Nutzung von using namespace std;:

    Nicht, wenn man seine Spezialisierung im Namespace std implementiert:

    Aua, das ist ein absolutes No-go.



  • @john-0
    Nö, das ist vom Kommittee sogar explizit erlaubt worden. Man spezialisiert seine swap Funktion im std-namespace. Man muss seine swap-Funktion aber als Spezialisierung implementieren, nicht als Überladung. Bis C++20 jedenfalls.

    Edit:
    Referenz siehe Box "Specializations"



  • @DocShoe sagte in Nutzung von using namespace std;:

    @john-0
    Nö, das ist vom Kommittee sogar explizit erlaubt worden. Man spezialisiert seine swap Funktion im std-namespace. Man muss seine swap-Funktion aber als Spezialisierung implementieren, nicht als Überladung. Bis C++20 jedenfalls.

    Ok, wieder was gelernt. Wobei ich mich nicht ganz falsch erinnere, denn da steht ja.

    std::swap may be specialized in namespace std for program-defined types, but such specializations are not found by ADL (the namespace std is not the associated namespace for the program-defined type).

    D.h. es ist zwar möglich bis C++20 ist es aber nicht sinnvoll, weil es ggf. nicht gefunden wird.


  • Mod

    Im Gegensatz zur hier oft apodiktisch vertretenen Meinung, dass ein globales using namespace std; universell schwachsinnig ist und nur von Anfängern und Juergen Wolf eingesetzt wird, habe ich in professionellem Umfeld zu schätzen gelernt, dass selbst in riesigen Projekten std in zentralen Headern geöffnet wird. Es ist in der Praxis wirklich einfach unproblematisch. Ich würde es definitiv nicht in einer Bibliothek machen, da man ja nicht seine Idiome auf den User zwingen will, aber in einem eigenen Projekt ist es kein Thema.



  • @Columbo sagte in Nutzung von using namespace std;:

    Im Gegensatz zur hier oft apodiktisch vertretenen Meinung, dass ein globales using namespace std; universell schwachsinnig ist und nur von Anfängern und Juergen Wolf eingesetzt wird, habe ich in professionellem Umfeld zu schätzen gelernt, dass selbst in riesigen Projekten std in zentralen Headern geöffnet wird. Es ist in der Praxis wirklich einfach unproblematisch. Ich würde es definitiv nicht in einer Bibliothek machen, da man ja nicht seine Idiome auf den User zwingen will, aber in einem eigenen Projekt ist es kein Thema.

    Tja nö, es ist eben nicht generell unproblematisch. Bekanntestes Beispiel: max unter Windows.



  • Ich mache es nie global, aber durchaus lokal, wenn ich in einer Methode häufiger Dinge aus einem anderen Namespace verwende. Nicht unbedingt mit std, weil es nicht soviel tipparbeit ist, aber wenn die namespaces länger sind, nehme ich gern mal using namespace.


Log in to reply