Betrachten Sie den einfachen Code:
%Vor%Erstens bin ich mir nicht sicher, ob ich alles richtig verstehe, also korrigiere mich, wenn du mich bitte falsch findest.
Mein Verständnis war, dass void func(B)
gewählt werden sollte, da das Argument für func
ist A
, was der Klassentyp ist, daher ist die Art der Konvertierung erforderlich "Benutzerdefinierte Konvertierungssequenz"
Jetzt von IBM C ++ ref:
Eine benutzerdefinierte Konvertierungssequenz besteht aus Folgendem:
- Eine Standard-Konvertierungssequenz
- Eine benutzerdefinierte Konvertierung
- Eine zweite Standardkonvertierungssequenz
Jetzt sind zwei benutzerdefinierte Konvertierungen vorhanden
B::B(const A&)
und A::operator int (const A&);
so ist die Reihenfolge
- & gt; A()
- & gt; B::B(const A&)
- & gt; Standard conversion (identity conversion)
- & gt; A()
- & gt; A::operator int (const A&)
- & gt; Standard conversion (integral conversion)
da die Integralumwandlung schlechter als die Identitätsumwandlung ist, dachte ich, dass void func(B)
aufgerufen würde, aber der Aufruf noch nicht eindeutig ist.
Bitte helfen Sie mir, an welcher Stelle ich falsch liege und warum der Anruf mehrdeutig ist. Vielen Dank:)
Die beiden Konvertierungssequenzen hier, A -> B
und A -> int
, sind beide benutzerdefiniert , weil sie über Funktionen funktionieren, die Sie definiert haben.
Die Regel für das Ranking benutzerdefinierter Konvertierungssequenzen finden Sie in 13.3.3.2 (N3797):
Die benutzerdefinierte Konvertierungssequenz
U1
ist eine bessere Konvertierungssequenz als eine andere benutzerdefinierte KonvertierungssequenzU2
, wenn sie die gleiche benutzerdefinierte Konvertierungsfunktion oder den gleichen Konstruktor enthält oder wenn sie die gleiche Klasse in einer Aggregat-Initialisierung und in initialisieren In beiden Fällen ist die zweite Standardkonvertierungssequenz vonU1
besser als die zweite Standardkonvertierungssequenz vonU2
Diese beiden Konvertierungssequenzen enthalten nicht dieselbe benutzerdefinierte Konvertierungsfunktion und initialisieren nicht dieselbe Klasse in der Aggregat-Initialisierung (da initialisiert int
).
Es ist also nicht wahr, dass eine Sequenz über der anderen rangiert, daher ist dieser Code mehrdeutig.
so ist die Reihenfolge - & gt; A () - & gt; B :: B (const A & amp;) - & gt; Standardkonvertierung (Identitätskonvertierung)
Nein! Auszug aus dem Standard (Entwurf) [over.best.ics] (Hervorhebung von mir):
- Wenn no Konvertierungen erforderlich sind, um ein Argument einem Parametertyp zuzuordnen, ist die implizite Konvertierungssequenz die Standardkonvertierungssequenz, die aus der Identitätskonvertierung (13.3.3.1.1) besteht.
func(A())
ist keine Identität, es ist benutzerdefiniert. Wieder aus dem Standard, [[conv]] :
Für Klassentypen werden auch benutzerdefinierte Konvertierungen berücksichtigt. siehe 12.3. Im Allgemeinen besteht eine implizite Konvertierungssequenz (13.3.3.1) aus einer Standardkonvertierungssequenz gefolgt von einer benutzerdefinierten Konvertierung, gefolgt von einer anderen Standardkonvertierungssequenz.
Ich glaube, Sie haben ein Missverständnis bezüglich Standardkonvertierungen . Sie haben nichts mit benutzerdefinierten Typen / Klassen zu tun. Standardkonvertierungen sind nur für integrierte Typen verfügbar: Lvalue-to-Rvalue-Konvertierung, Array-to-Pointer-Konvertierung, Funktion-zu-Zeiger-Konvertierung, Integrated-Promotions, Floating-Point-Promotion, Integral-Conversions, Floating-Point-Conversions, Floating-Integral-Conversions. Zeigerkonvertierungen, Zeiger auf Elementkonvertierungen, Boolesche Konvertierungen und Qualifizierungskonvertierungen. A
- & gt; int
ist keine davon, sondern eine benutzerdefinierte Konvertierung. Der Standard für benutzerdefinierte Conversions, [[class.conv]] , d. H. 12.3:
Typkonvertierungen von Klassenobjekten können durch Konstruktoren und durch Konvertierungsfunktionen spezifiziert werden. Diese Konvertierungen werden als benutzerdefinierte Konvertierungen bezeichnet und werden für implizite Typkonvertierungen (Abschnitt 4), für die Initialisierung (8.5) und für explizite Typkonvertierungen (5.4, 5.2.9) verwendet.
Sie haben zwei benutzerdefinierte Konvertierungssequenzen mit demselben Rang (siehe die Antwort von M.M., warum), so dass der Compiler möchte, dass Sie disambiguieren.
Tags und Links c++ overload-resolution