Es gibt eine globale Funktion (nur ein Beispiel):
%Vor%Ich nehme an, dass das Aufrufen dieser Funktion mit char Argument keinen Sinn macht, also verwende ich delete:
%Vor%So erwarte ich, dass folgende Anrufe möglich sein sollten:
%Vor%Und Aufruf mit Char-Argument sollte verboten werden:
%Vor% Aber das ist nicht wahr. Beim Aufruf von func('a')
bekomme ich wie erwartet:
Aber beim Aufruf von func(2.3)
bekomme ich:
Warum bekomme ich diesen Fehler? Ohne die Funktion mit char-Argumenten zu löschen, wurde double in int konvertiert und func (int) wurde aufgerufen, warum ist es jetzt verboten?
Wenn Sie
anrufen %Vor% Sie übergeben ein double
an die Funktion. Die Liste der Kandidaten enthält sowohl func(int)
als auch func(char)
, da die Überladungsauflösung geschieht vor delete
tritt ein :
Wenn die Funktion überladen ist, wird zuerst die Überladungsauflösung durchgeführt, und das Programm wird nur schlecht dargestellt, wenn die gelöschte Funktion ausgewählt wurde Ref: cppreference.com, siehe Avishais Antwort für präzise Standard-Anführungszeichen.
Jetzt kann double
sowohl in char
als auch in int
konvertiert werden, daher die Mehrdeutigkeit.
Ohne die Funktion mit char-Argumenten zu löschen, wurde double in int konvertiert und func (int) wurde aufgerufen, warum ist es jetzt verboten?
Sie erhalten einen Mehrdeutigkeitsfehler auch ohne delete
in der char
version, siehe hier . Natürlich, wenn Sie nur func(int)
definieren, dann wird es keine Mehrdeutigkeit geben, so dass double
glücklich in ein int
konvertiert wird.
Immer wenn eine nicht exakte Übereinstimmung für einen Funktionsparameter übergeben wird, muss eine Konvertierung durchgeführt werden. Wenn Sie zwei Funktionen haben, unabhängig davon, ob eine gelöscht wird, nehmen sie immer noch an der Überladungsauflösung teil. Der Compiler wählt die beste Übereinstimmung aus und generiert dann entweder einen Aufruf oder schlägt fehl, wenn auf die Funktion nicht zugegriffen werden kann oder sie gelöscht wurde.
Damit die Überladungsauflösung funktioniert, stellt sie eine Gruppe von Kandidatenfunktionen zur Verfügung, die den kürzesten Konvertierungsweg zu dem Parametersatz sehen. Soweit die Regeln gehen, sind alle eingebauten numerischen Typen eine "gleiche" Umwandlung. Wenn Sie also mit 2.5 aufrufen, was ein Double ist, muss es konvertiert werden und kann in gleicher Weise in ein char OR in ein int umgewandelt werden, so dass der Aufruf mehrdeutig ist.
Es ist immer noch mehrdeutig, da der Compiler versucht, die Überladung aufzulösen, bevor nach gelöschten Funktionen gesucht wird. Siehe:
§8.4.3 Gelöschte Definitionen
Ein Programm, das implizit oder explizit auf eine gelöschte Funktion verweist, außer sie zu deklarieren, ist schlecht ausgebildet. [ Hinweis: Dies beinhaltet den Aufruf der Funktion implizit oder explizit und die Bildung eines Zeigers oder Zeigers an ein Mitglied zur Funktion. Dies gilt auch für Referenzen in Ausdrücken, die nicht potenziell ausgewertet werden. Wenn eine Funktion ist überlastet, wird nur referenziert, wenn die Funktion durch Überladungsauflösung ausgewählt wird. - Endnote ]
§13.3.3.1 Implizite Konvertierungssequenzen:
Implizite Konvertierungssequenzen betreffen nur den Typ, die cv-Qualifikation und die Wertkategorie von das Argument und wie diese konvertiert werden, um mit den entsprechenden Eigenschaften des Parameters übereinzustimmen. Andere Eigenschaften, wie die Lebensdauer, Speicherklasse, Ausrichtung, Zugänglichkeit des Arguments, ob das Argument ist ein Bitfeld und ob eine Funktion gelöscht wird (8.4.3), wird ignoriert. Also, obwohl eine implizite Konvertierung Sequenz kann für ein gegebenes Argument-Parameter-Paar definiert werden, die Umwandlung vom Argument in das Parameter könnten in der abschließenden Analyse noch schlecht gebildet sein.