2010-12-05 13 views
17

Es gibt überzeugende Argumente againstusing namespace std, warum wurde es überhaupt in die Sprache eingeführt? Vereitelt using namespace den Zweck von Namespaces nicht? Warum sollte ich jemals using namespace schreiben wollen? Gibt es ein Problem, von dem ich nicht weiß, dass es elegant gelöst wird durch using namespace, vielleicht in den Zeilen des using std::swap Idioms oder so ähnlich?Was ist der Zweck von: "Namespace verwenden"?

+11

Weniger Typisierung ist ein ziemlich verführerisch Argument ... – delnan

+0

Das Konzept der Verwendung von ‚mit‘ arbeitet rund um oder gegen den Namespace, aber es ist da, wenn du es brauchst. – kenny

+3

Siehe auch Herb Sutters ["Migrieren zu Namespaces."] (Http://www.gotw.ca/publications/migrating_to_namespaces.htm) –

Antwort

21

Zum einen ist dies die Art und Weise Betreiber Überlastungen in einem Namensraum zu verwenden (z using namespace std::rel_ops; oder using namespace boost::assign;)

Brevity ist auch ein starkes Argument. Würden Sie wirklich gerne tippen und lesen std::placeholders::_1 statt _1? Wenn Sie Code in funktionalem Stil schreiben, verwenden Sie außerdem eine Vielzahl von Objekten in den Namensbereichen std und boost.

Eine weitere wichtige Verwendung (obwohl normalerweise muss man nicht ganze Namensräume importiert) ist Argument abhängiger Nachschau zu aktivieren:

template <class T> 
void smart_swap(T& a, T& b) 
{ 
    using std::swap; 
    swap(a, b); 
} 

Wenn Swap ist für irgendeine Art von T im gleichen Namensraum wie T überlastet , das wird diese Überladung verwenden. Wenn Sie stattdessen explizit std::swap aufrufen, wird diese Überladung nicht berücksichtigt. Bei anderen Typen fällt dies auf std::swap zurück.

BTW, eine using-Deklaration/Direktive besiegt nicht den Zweck von Namespaces, da Sie den Namen im Zweifelsfall immer vollständig qualifizieren können.

+0

+ 1, das ist ein sehr convencing artument :) –

+2

Persönlich geht es mir gut mit "mit " ist es die "mit Namespace ", dass ich Probleme habe (mit ein paar Ausnahmen wie rel_ops). –

2

Die meiste Zeit ist es nur eine Abkürzung für das Schreiben von Code. Sie können Namen in Ihren umschließenden Kontext importieren. Normalerweise beschränke ich es auf .cpp Dateien, denn wenn Sie eine using-Anweisung in eine .h-Datei einfügen, verschmutzt es alle Dateien, in denen es enthalten ist. Eine weitere gute Methode besteht darin, die using namespace auf die möglichst umschließende Umgebung zu beschränken, beispielsweise innerhalb einer Methodenkörperdeklaration. Ich sehe es als eine Bequemlichkeit, nicht mehr, und ähnlichen Aliasing, wie zum Namensraum:

namespace po = boost::program_options; 

und dann können Sie

po::variables_map ... 
0

Menschen speziell auf using namespace std; aber nicht beschränkt auf using namespace BigCorp Objekt schreiben; oder auf std::cout beziehen (die den Namespace verwendet, nur nicht using es, wenn Sie wissen, was ich meine.) Auch die meisten Einwände gegen using namespace std sind in einer Header-Datei. In einer Quelldatei, in der die Effekte sofort sichtbar sind, ist sie weniger schädlich.

Namespaces sind ein unglaublich nützliches Konzept, das mir eine Klasse namens Date ermöglicht, obwohl eine Bibliothek, die ich verwende, eine Klasse namens Date hat. Bevor sie der Sprache hinzugefügt wurden, mussten wir Dinge wie GCDate und GCString (meine Firma, Gregory Consulting, vor std::string) haben. Durch die Verwendung von Namespaces (mit oder ohne das Schlüsselwort using) können wir alle saubereren, saubereren Code schreiben. Aber wenn man jedes Mal Gregcons::string sagen muss, verliert man den saubereren, saubereren Teil. [Haftungsausschluss: Ich verwende nicht mehr meine eigene String-Klasse - stellen Sie sich einen passenden Namenskonflikt vor.] Das ist der Reiz der using Aussage. Halten Sie es aus den Headern heraus, wenden Sie es nicht auf std an, und Sie sollten generell keine Probleme haben.

+0

Ich würde sagen, benutze 'using namespace foo' nicht, sondern' foo :: whatever'; das gilt sowohl für Standardnamen als auch für andere Namen. Zum Beispiel ist nichts falsch daran, 'std :: cout 'zu verwenden, wenn nicht in einer Kopfzeile. – celtschk

0

Ich finde es nützlich, wenn Sie mit Bibliotheken mit tief verschachtelten Namespaces arbeiten. Die Boost-Bibliothek ist ein solches Beispiel. Imaging Typisierung boost::numeric::ublas::matrix<double> m überall ...

Die Sache zu vermeiden ist using namespace in einer Header-Datei zu tun, da dies das Potenzial hat, verschwenderisch jedes Programm, das den Header enthält. Platzieren Sie using namespace-Anweisungen immer in .cpp/.cxx-Dateien, sodass sie auf den Dateibereich beschränkt sind.

+2

aber ein Namespace-Alias ​​konnte das genauso gut lösen. Oder Sie können nur selektiv "Matrix" importieren. – jalf

+2

Oder Sie könnten eine Typedef, z. 'typedef boost :: numeric :: ublas :: matrix DoubleMatrix' und verwende' DoubleMatrix' im Rest deines Codes. Das ist die Schönheit/der Fluch von C++: Es gibt mehrere Ansätze, um das gleiche Problem zu lösen. – CadentOrange

-1

"Namespaces ermöglichen das Gruppieren von Entitäten wie Klassen, Objekten und Funktionen unter einem Namen. Auf diese Weise kann der globale Bereich in" Unterbereiche "mit jeweils eigenem Namen unterteilt werden. Bezeichner sind gültige Bezeichner und Entitäten ist der Satz von Klassen, Objekte und Funktionen, die im Namensraum enthalten sind“

Weitere Informationen hier: http://www.cplusplus.com/doc/tutorial/namespaces/

1

der Hauptgrund, warum using namespace war die abwärts~~POS=TRUNC eingeführt wurde: Wenn Sie viele Pre-Namespace-Code haben mit vielen (vor-standard-Versionen von) Standard-Bibliothek Funktionen und Klassen, wollen Sie eine einfache Möglichkeit, das zu machen Code arbeitet mit einem standardkonformen Compiler.

BTW, die Argument abhängige Lookup-Regeln zumindest für 98 C++ bedeuten, dass using namespace std::rel_ops wird nicht tun, was Sie in Vorlagen wollen (ich weiß nicht, ob dies in einer späteren Version des Standards geändert).

Beispiel:

template<typename T> bool bar(T t) 
{ 
    return t > T(); 
} 

namespace foo 
{ 
    class X {}; 
    bool operator<(X, X); 
} 

using namespace std::rel_ops; 

int main() 
{ 
    X x; 
    bar(x); // won't work: X does not have operator> 
} 

Beachten Sie, dass die using namespace in namespace foo setzen wird nicht helfen.

jedoch Erklärungen an der richtigen Stelle Hilfe bei der Verwendung:

template<typename T> bool bar(T t) 
{ 
    return t > T(); 
} 

namespace foo 
{ 
    class X {}; 
    bool operator<(X, X); 
    using std::rel_ops::operator>; 
} 

int main() 
{ 
    X x; 
    bar(x); // now works: operator> found per ADL via the using declaration in `namespace foo` 
}