Hab ein fehler
-
@HumeSikkins: Guck mal nen paar Threads weiter oben
@Chenoa: Pack oben noch #include <limits> rein, wenn du meinen Code nutzt. Hab ich vergessen gehabt. Sry.
-
(D)Evil schrieb:
@HumeSikkins: Guck mal nen paar Threads weiter oben
würde die erklärung auch gerne hören und alle threads im c++ forum durchsuchen ist mir jetzt etwas zuviel :p
-
HumeSikkins schrieb:
darthdespotism schrieb:
aber wozu das using namespace? Ist generell eine schlechte Idee
Ist das irgendwie dein Steckenpferd? Nenn doch bitte mal einen technischen Grund, warum eine using-Direktive *nach* allen Includes innerhalb einer *Source*-Datei eine schlechte Idee ist.
Nehmen wir an du hast zwei tolle Klassen: std::string und gott::string. Jetzt machst du
using namespace std; using namespace gott; string x; // KABOOMUm sowas zu vermeiden und um konsistent zu bleiben nutze ich zumindest (fast) nie "using namespace".
Ob dir das technisch genug ist, ist mir allerdings egal.

-
darthdespotism schrieb:
using namespace std; using std::cout; using std::endl;Wow das ist mal was

für die Letzten 2
aber wozu das using namespace? Ist generell eine schlechte Idee und du greifst nicht darauf zurückIch mache nur das was in mein Buch steht(Meine jetzt mir using namespace std;)
-
Mr. N schrieb:
Nehmen wir an du hast zwei tolle Klassen: std::string und gott::string. Jetzt machst du
using namespace std; using namespace gott; string x; // KABOOMUm sowas zu vermeiden und um konsistent zu bleiben nutze ich zumindest (fast) nie "using namespace".
Ob dir das technisch genug ist, ist mir allerdings egal.

Es ist jedenfalls nicht *Grund* genug. Das ist nämlich einfach nur Quatsch. In solch einem Fall verwendet man dann halt Aliase oder gibt den Namensbereich explizit an, indem man den Bezeichner voll qualifiziert. Ich sehe hier keinen Grund, 'using'-Direktiven generell zu vermeiden.
-
ich benutze sehr sehr selten 2 verschiedene arten von strings. oder generell 2 verschiedene arten von irgendwas.
die probleme die man mit 2 gleichen namen hat, ist übrigens nicht durch ein using namespace zu lösen. denn ist string nun xxx::string oder yyy::string. das ist viel wichtiger und schwergewichter als der compiler fehler.
-
Shade Of Mine schrieb:
ich benutze sehr sehr selten 2 verschiedene arten von strings. oder generell 2 verschiedene arten von irgendwas.
Hmm. Jein. Genau das ist ja der Sinn von Namensbereichen: Solche Konflikte zu vermeiden.
-
Shade Of Mine schrieb:
ich benutze sehr sehr selten 2 verschiedene arten von strings. oder generell 2 verschiedene arten von irgendwas.
die probleme die man mit 2 gleichen namen hat, ist übrigens nicht durch ein using namespace zu lösen. denn ist string nun xxx::string oder yyy::string. das ist viel wichtiger und schwergewichter als der compiler fehler.
Dann nimm halt immer den globalen Namespace.

-
Konrad Rudolph schrieb:
Shade Of Mine schrieb:
ich benutze sehr sehr selten 2 verschiedene arten von strings. oder generell 2 verschiedene arten von irgendwas.
Hmm. Jein. Genau das ist ja der Sinn von Namensbereichen: Solche Konflikte zu vermeiden.
Du hast es nicht verstanden. Das Problem ist:
string s;
ist das jetzt xxx::string oder yyy::string?
ob ich hier using namespace xxx; oder using xxx::string; schreibe ist dabei vollkommen egal. sobald ich 2 gleiche sachen in einem projekt habe, habe ich ein problem.ich kann also sorglos using namespace std; schreiben. denn ob ich es schreibe oder nicht, ich verwirre die leute mit 2 strings so oder so. und muss dann einen string immer mit namespace schreiben wenn nicht sogar beide.
wie dem auch sei, ich bin teufels küche.
compiler fehler sind hierbei das geringste übel: viel größer sind die logischen probleme für den programmierer
-
Mr. N schrieb:
HumeSikkins schrieb:
darthdespotism schrieb:
aber wozu das using namespace? Ist generell eine schlechte Idee
Ist das irgendwie dein Steckenpferd? Nenn doch bitte mal einen technischen Grund, warum eine using-Direktive *nach* allen Includes innerhalb einer *Source*-Datei eine schlechte Idee ist.
Nehmen wir an du hast zwei tolle Klassen: std::string und gott::string. Jetzt machst du
using namespace std; using namespace gott; string x; // KABOOMUm sowas zu vermeiden und um konsistent zu bleiben nutze ich zumindest (fast) nie "using namespace".
Ob dir das technisch genug ist, ist mir allerdings egal.

Also erstmal ist das KABOOM völliger blödsinn, da es suggeriert, dass etwas schlimmes passiert. Eine Compile-Zeit-Fehler, der durch den Compiler mit Name und Adresse gemeldet wird ist aber wahrlich nichts schlimmes, gehört bei einer statisch getypten Sprache wie C++ vielmehr zum Alltag. Mit KABOOM sollte man Sachen bezeichnen, die zu einem Unglück führen und die nicht vom Compiler entdeckt werden (müssen). Wie z.B. undefiniertes Verhalten.
Als nächstes:
Nehmen wir dein Beispiel:
A) Ohne Using-Direktiven und using-Deklaration:#include <string> #include <gott> void alles_noch_gut() { std::string question = "May I have your attention, please?" Gott::getInstance().askGott(question); ... } void spaet_in_der_nacht() { string question = "Why do I have to work at night?"; // Compile-Zeit-Fehler }Du (oder der nächste Programmierer) vergisst die Namespace-Qualifikation. Ergebnis: Compile-Zeit-Fehler. Unbekannter Typ.
Fix: Qualifizieren
Mit Using-Deklaration:#include <string> #include <gott> using gott::string; .... // spaet in der nacht using std::string;Du (oder der nächste Programmierer) fügt eine zweite (inkompatible) using-Deklaration hinzu: Ergebnis: Compile-Zeit-Fehler. Name bereits deklariert.
Fix: Qualifizieren
C) Mit Using-Direktive:#include <string> #include <gott> using namespace gott; using namespace string; void alles_noch_gut() { std::string question = "May I have your attention, please?" Gott::getInstance().askGott(question); ... } void spaet_in_der_nacht() { string question = "Why do I have to work at night?"; // Compile-Zeit-Fehler }Du (oder der nächste Programmierer) verwendest einen Namen, der durch eine using-Direktive mehrdeutig geworden ist. Ergebnis: Compile-Zeit-Fehler. Name ist mehrdeutig.
Fix: QualifizierenWie man sieht: Die Fehler sind nahezu identisch und alle werden vom Compiler bemängelt. Der Fix ist immer der selbe. Technisch gibt es *keinen* Unterschied (immer unter der Annahme, dass wir *nach* allen includes und in Source-Datei sind). Die Fehler sind immer lokal und einmal gefixed ist die Semantik in allen Fällen die Gleiche. Der Unterschied besteht lediglich darin, wann der Fehler auftritt und wann die Arbeit investiert werden muss.
Im Computerdeutsch könnte man den Immer-Qualifizierer als eager bezeichnen. Den using-Direktiven-Mensch als lazy.
Wer hier von einer Stilverletzung spricht, verwechselt in meinen Augen Stil mit Geschmack.
-
Die Gefahr, dass man zwei inkompatible using-Direktiven setzt ist doch wesentlich geringer als die Gefahr, inkompatible using namespace-Direktiven zu setzen. Das ist natürlich subjektiv.
Ich nutze using allerdings grundsätzlich wesentlich weniger als früher. Schreibe also jedes mal std::cout und std::string. Stört ja auch nicht wirklich.

-
Worum es aber geht ist, es schadet dir nicht using namespace std; in einer implementierungsdatei zu schreiben. es ist nicht der einzige weg, aber es ist auch nicht ein falscher weg.
wenn man gerne viel :: schreibt, kann man komplett ohne using auskommen. wenn man lieber weniger schreibt oder leichtes lesen bevorzugt wird man lieber zu usings verfallen.
problem ist halt bei der lesbarkeit dass std:: null information für den leser sind...
-
es gibt keine "gefahr" bei verwendung von using namespace. fehler, die der compiler nicht entdeckt stellen eine gefahr da. fehler, die der compiler immer findet und auch ausschmeisst sind keine gefahr. was sich nicht kompilieren lässt, kann auch nicht gefährlich sein

using declarations können unschön sein, weil sie u.u. mehrarbeit verursachen und es deshalb sinnvoll ist, sie sparsam einzusetzen. zumindest nicht in header-dateien.
-
Vor ner ganzen weile wurde hier in nem ähnlichen Thema von jemandem sehr gut begründet, dass using std::string unter umständen schlimmer sein kann, als using namespace std...aber ich erinner mich nicht mehr an die begründung

Vielleicht liest derjenige das nochmal und verweist auf den thread.
-
Shade Of Mine schrieb:
Du hast es nicht verstanden. Das Problem ist:
string s;
ist das jetzt xxx::string oder yyy::string?
ob ich hier using namespace xxx; oder using xxx::string; schreibe ist dabei vollkommen egal. sobald ich 2 gleiche sachen in einem projekt habe, habe ich ein problem. […]compiler fehler sind hierbei das geringste übel: viel größer sind die logischen probleme für den programmierer
Nicht unbedingt. Zufälligerweise habe ich vor kurzem an einem Projekt mitgearbeitet, wo genau dies der Fall ist. Die Bibliothek ist ein Toolsatz für Bioinformatiker, und hier braucht man nunmal unterschiedliche Stringtypen. Unter anderem hat die Bibliothek eben auch eine Klasse libname::string<> definiert ('std::basic_string' wäre hier übrigens keine Alternative gewesen). Und schon hast Du Deinen Konflikt.
-
otze schrieb:
Vor ner ganzen weile wurde hier in nem ähnlichen Thema von jemandem sehr gut begründet, dass using std::string unter umständen schlimmer sein kann, als using namespace std...aber ich erinner mich nicht mehr an die begründung

Die ausführliche Begründung findest du in Sutters "More Exceptional C++" und das Ganze stimmt für usings in Headern. Ganz kurz: was eine using-Deklaration bedeutet hängt vom Kontext ab, in dem sie steht. Da es sich um eine (weitere) Deklaration handelt, werden nur solche Namen berücksichtigt, die bereits deklariert sind. Da Namespaces nun aber offen und gerne mal über mehrere Header verteilt sind, ist die genaue Bedeutung einer using-Deklaration in einem Header von der Reihenfolge abhängig, in der verschiedene Header am Ende inkludiert werden. Das ist nicht nur unangenehm, es kann auch schnell zu einer Verletzung der ODR (gerne mal bei inline-Funktionen) und damit zu undefiniertem Verhalten führen.
Eine using-Direktive hingegen, ist nicht ganz so dramatisch, da sie alle Namen verfügbar macht. Unabhängig davon ob selbige vor oder nach der using-Direktive deklariert werden. In diesem Punkt ist eine using-Direktive also Reihenfolgeunabhängig.
Trotzdem gehören sie nicht in Header (oder vor irgendwelche includes): Zum einen ist es unhöflich jedem alle Namen eines Namespaces aufzuzweingen und zum anderen kann es die Bedeutung von anderen Headern ändern, die ohne using im Hinterkopf geschrieben wurden.
-
Shade Of Mine schrieb:
problem ist halt bei der lesbarkeit dass std:: null information für den leser sind...
Wenn ich lese std::string, dann ist 100% und ohne Zweifel klar, was das ist. Bei "string" ist das weniger klar. Außerdem sind ellenlange using-Leisten unschön. (Und die entstehen selbst wenn man "using namespace" benutzt unter Umständen.)
Das Beispiel mit std::string und gott::string war übrigens nicht aus der Luft gegriffen. Aber jetzt ist GOTT ja eh mehr oder weniger "beendet".
