Das liegt daran, dass using namespace X
und using X::Y
anders arbeiten. Wenn Sie using namespace X
verwenden, wird alles, was sich in diesem Namespace befindet, während der Namenssuche berücksichtigt. Betrachten Sie das folgende Beispiel:
Hier werden die beiden Member A
und B
bei der Namenssuche berücksichtigt, und Sie erhalten den Fehler call of overloaded foo(int) is ambiguous
, da der Compiler nicht entscheiden kann, welche der beiden Funktionen verwendet werden soll, da sie identisch sind . Die using X::Y
-Syntax soll dieses Problem lösen. Wenn Sie es verwenden, weisen Sie den Compiler an, nur den in Y
Namespace gefundenen X
zu verwenden, ohne etwas anderes zu berücksichtigen. Fügen wir es dem obigen Beispiel hinzu:
Hier teilen wir dem Compiler mit, die Instanz von foo
zu verwenden, die im Namespace A
gefunden wurde, und ignorieren alle anderen foo
s im Gültigkeitsbereich. In Ihrem Beispiel weisen Sie den Compiler an, nur primerlib::compute
zu verwenden, und Sie müssen ::compute()
verwenden, wenn Sie auf die Funktionen aus dem globalen Bereich zugreifen und compute(int)
aufrufen möchten.
mit primerlib :: compute;
Dies ist eine using
Deklaration. Wenn Sie es verwenden, ist es so, als ob ein Name an der Stelle deklariert wird, an der die Deklaration verwendet wird. Sie können global foo
zurückholen, indem Sie using ::foo;
hinzufügen (oder den globalen Bereich ::foo(0);
aufrufen und in der Ausgabe ::compute(int)
sehen.
Die Tatsache, dass in Ihrem Beispiel der Compiler die globale foo
-Deklaration nicht findet, liegt daran, dass die Namenssuche so funktioniert - sie durchsucht einschließende Bereiche und Stopps, sobald ein Name gefunden wurde.
Weitere Informationen zur Verwendung der Deklaration finden Sie in Ссылка
[Bearbeiten]
Ich habe Ihre Frage missverstanden, in Zeile 17 haben Sie 'using directive', sie verhält sich anders als using declaration
, sie führt den Namen nicht in die nächstgelegene umschließende deklarative Region ein (in diesem Fall ihre Hauptfunktion), sondern fügt Namen zum nächsten hinzu Einschließender Namespace - in diesem Cast ist es globaler Namespace. Für mehr Referenz: Ссылка :
Using-Direktiven sind nur im Namespace-Bereich und im Block-Bereich erlaubt. Aus der Sicht der unqualifizierten Namenssuche eines beliebigen Namens nach einer using-Direktive und bis zum Ende des Bereichs, in dem er angezeigt wird, ist jeder Name von namespace-name sichtbar, als wäre er in deklariert nächster einschließender Namespace , der sowohl die using-Direktive als auch den Namespace-name enthält.
using-directive fügt der deklarativen Region, in der erscheint, keine Namen hinzu (im Gegensatz zur using-Deklaration) und verhindert damit nicht, dass identische Namen verwendet werden erklärt.
Mit der tatsächlichen using-Deklaration sagen Sie, dass compute ein Name ist, der nur auf die im namespace priiderlib definierte Funktion verweist: Wenn Sie tatsächlich die compute-Funktion aufrufen, die ein double akzeptiert, erhalten Sie den Fehler no passing function . Mit der kommentierten using-Deklaration geben Sie allen Rechenfunktionen die "gleiche Wichtigkeit": Um auf globale zu verweisen, müssen Sie die Namespace-Auflösungsdirektive "::" verwenden, um auf die Namespace-Einsen des Primers zu verweisen, Sie müssen die "primerlib" verwenden :: "Namespace-Auflösungsrichtlinie.
using directive
und using declaration
verhalten sich in diesem Fall anders.
7.3.4 $ 2 Verwendung der Anweisung [namespace.udir]: (fett von mir)
Eine using-Direktive gibt die Namen im nominierten Namespace an kann in dem Bereich verwendet werden, in dem die using-Direktive danach erscheint die Verwendungsrichtlinie. Bei unqualifizierter Namenssuche (3.4.1) die Namen erscheinen, als ob sie im nächsten einschließenden Namespace deklariert wären welches die using-Direktive und den nominierten Namespace enthält. [ Hinweis: "Enthält" bedeutet in diesem Zusammenhang "enthält direkt oder indirekt". -Hinweis]
In diesem Fall ist der nächste einschließende Namespace der globale Namaspace, die Funktionen des Namespace primerlib
erscheinen im selben Namespace mit anderen globalen Funktionen, also wurde nach der Überladungsauflösung ::compute(int)
aufgerufen.
7.3.3 $ 1 Die using-Deklaration [namespace.udecl]:
Eine using-Deklaration führt einen Namen in die deklarative Region ein was die using-Deklaration erscheint.
Die Funktionen des Namespace primerlib
werden in den Funktionsbereich main
eingefügt und in der Stufe der Namenssuche mit hoher Priorität ausgewählt. Dann wird die Namenssuche beendet. Die globalen Funktionen werden nicht für die Überladungsauflösung berücksichtigt, daher wurde primerlib::compute(const void *p)
aufgerufen.
BTW: Wenn Sie using primerlib::compute;
aus der Funktion main
entfernen, erhalten Sie dasselbe Ergebnis wie in using namespace primerlib;
in main
function.
Tags und Links c++