nicht statische Elementfunktionen, wie die beiden:
void func(double); // #1
void func(int) const; // #2
nehmen auch eine implicit object parameter, die in die Überladungsauflösung ([over.match]/p1) wie jedes andere Argument gilt:
Overload resolution is a mechanism for selecting the best function to call given a list of expressions that are to be the arguments of the call and a set of candidate functions that can be called based on the context of the call. The selection criteria for the best function are the number of arguments, how well the arguments match the parameter-type-list of the candidate function, how well (for non-static member functions) the object matches the implicit object parameter, and certain other properties of the candidate function.
Nachdem die implizite Einbeziehung Object-Parameter in die Member-Funktionen Signaturen, sieht der Compiler zwei Überladungen:
void func(Base&, double); // #1
void func(const Base&, int); // #2
und versucht, die beste tragfähige Funktion basierend auf dem Anruf zu wählen:
Base base;
base.func(1);
Die Umwandlung base
-Base&
(die ein nicht-const lvalue vom Typ Base
ist) einen Exact Match Rang (direkten Referenzbindung ergibt Identity conversion) - siehe Table 13.Die Umwandlung von base
zu const Base&
ist auch einen Exact Match Rang jedoch [over.ics.rank]/p3.2.6#1
deklariert eine bessere Conversion-Sequenz zu haben:
— S1 and S2 are reference bindings ([dcl.init.ref]), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers. [ Example:
int f(const int &);
int f(int &);
int g(const int &);
int g(int);
int i;
int j = f(i); // calls f(int &)
int k = g(i); // ambiguous
nun für den zweiten Parameter, eine Umwandlung von einem integralen prvalue 1
-double
ist ein Floating-Integral-Konvertierung ([conv.fpint]), die eine Conversion Rang gegeben wird. Andererseits ist 1
bis int
eine Identitätskonvertierung, die von einem Exact Match Rang ist. Für dieses Argument wird #2
betrachtet eine bessere Umwandlungsfolge haben ([over.ics.rank]/p3.2.2):
— the rank of S1 is better than the rank of S2, or S1 and S2 have the same rank and are distinguishable by the rules in the paragraph below, or, if not that, [...]
Überlastungs Auflösung erfolgreich zu sein braucht, dass es höchstens einen Parameter existiert, für die Konvertierungssequenzen unterscheiden ([over.match.best]):
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
— for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that, [...]
Hier ICS (# 1) ist besser als ICS (# 2), aber wiederum ICS (# 2) ist besser als ICS (# 1), so kann der Compiler nicht zwischen den beiden Überladungen wählen und Mehrdeutigkeiten erkennen.
Ganzzahlen können einfach in Fließkommatypen konvertiert werden. Während 'func (int)' die beste Übereinstimmung ist, ist 'func (double)' immer noch eine brauchbare Alternative, die den Aufruf mehrdeutig macht. –
Sie scheinen in eine knifflige Logik zu geraten, die const und nicht-const Elementfunktionen beinhaltet. FWIW, das 'func (double)' in eine 'const'-Member-Funktion ändert, behebt das Problem. –