c ++ mit Deklaration und Funktionsüberladung

8
%Vor%

Ausgabe:

primerlib::print(const void *p)

meine Frage ist, warum es nicht das globale compute (int) genannt hat? Wenn ich benutze Direktive in Zeile 17 und es wird die compute (int) aufrufen. Ihre Hilfe wird sehr geschätzt.

    
ponypaver 28.08.2015, 07:49
quelle

4 Antworten

4

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:

%Vor%

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:

%Vor%

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.

    
SingerOfTheFall 28.08.2015 08:17
quelle
1
  

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.

    
marcinj 28.08.2015 08:17
quelle
0

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.

    
alessandro mercadante 28.08.2015 08:18
quelle
0

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.

LIVE

    
songyuanyao 28.08.2015 08:48
quelle

Tags und Links