Ich habe den folgenden Code:
%Vor%Die Ausgabe ist:
%Vor% Meine Frage ist: Woher weiß der Compiler, welche Funktion aufgerufen werden soll? Wenn ich die Referenzen aus den Funktionsdefinitionen entferne, erhalte ich einen Fehlertyp "mehrdeutiger Aufruf", d. H.% Co_de%. Für mich sieht es so aus, als könnte error: redefinition of 'f'
für beide Aufrufe gleich gut verwendet werden, warum wird die f(T&)
version eindeutig für const
?
Bei zwei konkurrierenden Überladungen verlangt der Standard, dass der Compiler die Überladung auswählt, die die beste Anpassung aufweist. (Wenn es keine eindeutige beste Überladung gibt oder wenn die einzigartige beste Überladung nicht zugänglich ist, ist das Programm schlecht gebildet.)
In diesem Fall werden die Regeln von §13.3.3.2 [over.ics.rank] / p3:
bereitgestelltDie Standard-Umwandlungssequenz S1 ist eine bessere Umwandlungssequenz als die Standard-Umwandlungssequenz S2, wenn:
[...]
S1 und S2 sind Referenzbindungen (8.5.3), und die Typen, auf die sich die Verweise beziehen, sind vom selben Typ, mit Ausnahme von CV-Qualifikationsmerkmalen auf oberster Ebene und dem Typ, auf den sich die durch S2 initialisierte Referenz bezieht ist cv-qualifiziert als der Typ, auf den sich die durch S1 initialisierte Referenz bezieht.
Dies ist das Beispiel im Standard:
%Vor% In Ihrem Fall ist const T&
mehr cv-qualifiziert als T&
. Daher ist f(T&)
im Standard besser geeignet als f(const T&)
und wird durch Überladungsauflösung ausgewählt.
f(T&)
vs. f(T const&)
Die zwei Funktionen sind unterschiedlich, da die erste Signatur angibt, dass jede Variable, die durch Referenz übergeben wird, durch die Funktion modifiziert werden kann. So kann der const float nicht an die erste Funktion übergeben werden, und die zweite ist die einzig mögliche Wahl für den Compiler. Eine Nonconst-Variable könnte an beide übergeben werden, so dass der Compiler die bessere Anpassung auswählen muss, falls es eine gibt. Der Standard sagt, dass, um die zweite Funktion aufzurufen, der Compiler eine const
zu einer beliebigen nonconst-Variablen hinzufügen muss, während dies für die erste Funktion nicht notwendig ist. Das Hinzufügen von const ist eine implizite Konvertierung, und es ist eine "schlechtere" Konvertierung (lesen Sie das als more Konvertierungsschritte), als nichts hinzuzufügen. Daher fordert der Standard, dass der Compiler die erste Funktion auswählt, wenn er Nonconst-Variablen übergibt.
Falls Sie sich fragen: Literale und Provisorien können nicht an Nonconst-Referenzen gebunden sein, also werden f(4)
, f("meow")
und f(someFunc())
alle die zweite Funktion aufrufen.
f(T)
vs. f(const T)
Sie sehen anders aus, sind aber nicht in Bezug auf Überladungsauflösung oder Funktionssignatur. Beide sind call by value oder für den Compiler: Übergeben Sie eine Kopie des Arguments in die Funktion. Der einzige Unterschied besteht in einer Funktionsdefinition, bei der die Variable im Funktionskörper konstant sein muss. Eine Funktionsdeklaration wirkt sich nicht auf die Variablendefinition in der Signatur der Funktionsdefinition aus:
Dies ist kein "ambuguos call type error", weil es für den Compiler nur eine Funktion und keine Mehrdeutigkeit gibt. Der Fehler ist einfach, dass Sie zweimal die gleiche Funktion definiert haben. Aus diesem Grund wird in vielen Styleguides bevorzugt, dass Funktionsdeklarationen keine Const der obersten Ebene haben, und Compiler ignorieren diese häufig und erwähnen sie nicht in Fehler- oder Warnmeldungen.
Tags und Links c++ pass-by-reference