class C {
using namespace std; // error
};
namespace N {
using namespace std; // ok
}
int main () {
using namespace std; // ok
}
Bearbeiten : Willst du die Motivation dahinter wissen.
c++
namespaces
using
language-lawyer
iammilind
quelle
quelle
using namespace
. C # erlaubt etwas Ähnliches, jedoch nur im Dateibereich. Mit C ++using namespace
können Sie einen Namespace in einen anderen integrieren.class/struct
. Es ist einfach nicht erlaubt. Die akzeptierte Antwort diskutiert jedoch eine sehr logische Begründung, um sie nicht zuzulassen. dh wo zu berücksichtigenHello::World
und wo zu berücksichtigenWorld
. Hoffe das klärt den Zweifel.Antworten:
Ich weiß es nicht genau, aber ich vermute, dass das Zulassen im Klassenbereich Verwirrung stiften kann:
Da es keinen offensichtlichen Weg gibt, dies zu tun, sagt der Standard nur, dass Sie nicht können.
Der Grund dafür ist weniger verwirrend, wenn es um Namespace-Bereiche geht:
quelle
using namespace Hello;
Innere des Anderennamespace
(und das Deklarieren derextern
Funktion darin).Hello::World Blah::DoSomething()
oderBlah::World Blah::DoSomething()
(wenn es erlaubt war), der Rückgabetyp einer Elementfunktionsdefinition wird nicht als im Umfang der Klasse in der Sprache liegend angesehen, daher muss er qualifiziert werden. Betrachten Sie das gültige Beispiel für das Ersetzen vonusing
durch einentypedef Hello::World World;
at-Klassenbereich. Es sollte also keine Überraschungen geben.Weil der C ++ - Standard dies ausdrücklich verbietet. Ab C ++ 03 §7.3.4 [namespace.udir]:
Warum verbietet der C ++ - Standard dies? Ich weiß nicht, fragen Sie ein Mitglied des ISO-Komitees, das den Sprachstandard genehmigt hat.
quelle
Ich glaube, das Grundprinzip ist, dass es wahrscheinlich verwirrend wäre. Derzeit wird bei der Verarbeitung einer Kennung auf Klassenebene die Suche zuerst im Klassenbereich und dann im umschließenden Namespace gesucht. Das Zulassen
using namespace
auf Klassenebene hätte einige Nebenwirkungen auf die Art und Weise, wie die Suche jetzt durchgeführt wird. Insbesondere müsste es irgendwann zwischen der Überprüfung dieses bestimmten Klassenbereichs und der Überprüfung des umschließenden Namespace durchgeführt werden. Das heißt: 1) Zusammenführen der Suchvorgänge auf Klassenebene und verwendeter Namespace-Ebene, 2) Nachschlagen des verwendeten Namespace nach dem Klassenbereich, jedoch vor jedem anderen Klassenbereich, 3) Nachschlagen des verwendeten Namespace direkt vor dem umschließenden Namespace. 4) Suche mit dem umschließenden Namespace zusammengeführt..
.
.
using
Deklaration auf Namespace-Ebene. Dies würde keinen neuen Wert hinzufügen, würde jedoch die Suche nach Compiler-Implementierern erschweren. Die Suche nach Namespace-IDs ist jetzt unabhängig davon, wo im Code die Suche ausgelöst wird. Wenn in einer Klasse die Suche den Bezeichner im Klassenbereich nicht findet, wird auf die Namespace-Suche zurückgegriffen. Dies ist jedoch genau die gleiche Namespace-Suche, die in einer Funktionsdefinition verwendet wird. Es ist nicht erforderlich, einen neuen Status beizubehalten. Wenn dieusing
Erklärung auf Namespace - Ebene gefunden wird, wird der Inhalt des verwendeten sind Namensraum gebracht , in diesem Namensraum für alle Lookups den Namensraum beinhaltet. Wennusing namespace
Wurde auf Klassenebene zugelassen, würde es unterschiedliche Ergebnisse für die Namespace-Suche mit genau demselben Namespace geben, je nachdem, von wo aus die Suche ausgelöst wurde, und dies würde die Implementierung der Suche ohne zusätzlichen Wert viel komplexer machen.Ich empfehle jedenfalls, die Erklärung überhaupt nicht zu verwenden
using namespace
. Es macht es einfacher, mit Code zu argumentieren, ohne den Inhalt aller Namespaces berücksichtigen zu müssen.quelle
using
. Indem wir Dinge absichtlich in tief verschachtelten langen Namespaces deklarieren. ZBglm
tut dies und verwendet mehrere Tricks, um Funktionen zu aktivieren / präsentieren, wenn der Client sie verwendetusing
.using namespace std::placeholders
. cf en.cppreference.com/w/cpp/utility/functional/bindnamespace ph = std::placeholders;
Dies ist wahrscheinlich wegen Offenheit gegen Geschlossenheit nicht erlaubt.
Das Importieren von Namespaces in Klassen würde zu lustigen Fällen wie diesen führen:
quelle
Ich denke, es ist ein Sprachfehler. Sie können die unten stehende Problemumgehung verwenden. Unter Berücksichtigung dieser Problemumgehung ist es einfach, Regeln für die Lösung von Namenskonflikten für den Fall vorzuschlagen, dass die Sprache geändert wird.
quelle