Address of an overloaded function
Neben Funktionsaufrufausdrücken , wo Überladungsauflösung stattfindet, kann der Name einer überladenen Funktion in den folgenden 7 Kontexten erscheinen:
| # | Kontext | Ziel |
|---|---|---|
| 1 | Initialisierer in einer Deklaration eines Objekts oder einer Referenz | das zu initialisierende Objekt oder die Referenz |
| 2 | auf der rechten Seite eines eingebauten Zuweisungsausdrucks | die linke Seite der eingebauten Zuweisung |
| 3 | als Funktionsaufrufargument | der Funktionsparameter |
| 4 | als benutzerdefiniertes Operatorargument | der Operatorparameter |
| 5 |
die
return
Anweisung
|
der Rückgabewert einer Funktion oder Konvertierung |
| 6 |
explizite Umwandlung
oder
static_cast
Argument
|
die entsprechende Umwandlung |
| 7 | konstanter Templateparameter | der entsprechende Templateparameter |
In jedem Kontext darf der Name einer überladenen Funktion dem Adressoperator
&
vorangestellt werden und kann in einen redundanten Satz von Klammern eingeschlossen werden.
|
Wenn der Zieltyp einen Platzhaltertyp enthält, wird die Platzhaltertypableitung durchgeführt, und die folgende Beschreibung verwendet den abgeleiteten Typ als Zieltyp. |
(since C++26) |
Inhaltsverzeichnis |
Auswahl von Funktionen
Wenn die Adresse einer überladenen Funktion genommen wird, wird eine Menge
S
von Funktionen aus dem Überladungssatz ausgewählt, auf den durch den Namen der überladenen Funktion verwiesen wird:
- Wenn es kein Ziel gibt, werden alle benannten Nicht-Template-Funktionen ausgewählt.
-
Andernfalls wird eine Nicht-Template-Funktion mit Typ
Ffür den FunktionstypFTdes Zieltyps ausgewählt, wennF(nach möglicher Anwendung der Funktionszeigerkonvertierung ) (seit C++17) identisch mitFTist. [1] -
Die Spezialisierung (falls vorhanden), die durch
Template-Argumentableitung
für jede benannte Funktionsvorlage generiert wird, wird ebenfalls zu
Shinzugefügt.
Wenn das Ziel vom Typ Funktionszeiger oder Referenz auf Funktionstyp ist,
S
kann nur Nicht-Member-Funktionen enthalten
, explizite Objekt-Member-Funktionen
(seit C++23)
und statische Member-Funktionen. Wenn das Ziel vom Typ Zeiger-auf-Member-Funktion ist,
S
kann nur implizite Objekt-Member-Funktionen enthalten.
- ↑ Mit anderen Worten, die Klasse, von der die Funktion ein Mitglied ist, wird ignoriert, wenn der Zieltyp ein Zeiger-auf-Mitgliedsfunktion-Typ ist.
Eliminierung von Funktionen
Nach der Bildung der Menge
S
werden Funktionen in der folgenden Reihenfolge eliminiert:
|
(seit C++20) |
-
Wenn mehr als eine Funktion in
Sverbleibt, werden alle Funktions-Templatespezialisierungen inSeliminiert, fallsSauch eine Nicht-Template-Funktion enthält.
|
(since C++20) |
-
Jede gegebene Funktionstemplatespezialisierung
spec
wird eliminiert, falls
Seine zweite Funktionstemplatespezialisierung enthält, deren Funktionstemplate spezialisierter als das Funktionstemplate von spec ist.
Nach solchen Eliminierungen (falls vorhanden) sollte genau eine ausgewählte Funktion in
S
verbleiben. Andernfalls ist das Programm fehlerhaft.
Beispiel
int f(int) { return 1; } int f(double) { return 2; } void g(int(&f1)(int), int(*f2)(double)) { f1(0); f2(0.0); } template<int(*F)(int)> struct Templ {}; struct Foo { int mf(int) { return 3; } int mf(double) { return 4; } }; struct Emp { void operator<<(int (*)(double)) {} }; int main() { // 1. Initialisierung int (*pf)(double) = f; // wählt int f(double) int (&rf)(int) = f; // wählt int f(int) int (Foo::*mpf)(int) = &Foo::mf; // wählt int mf(int) // 2. Zuweisung pf = nullptr; pf = &f; // wählt int f(double) // 3. Funktionsargument g(f, f); // wählt int f(int) für das 1. Argument // und int f(double) für das zweite // 4. Benutzerdefinierter Operator Emp{} << f; // wählt int f(double) // 5. Rückgabewert auto foo = []() -> int (*)(int) { return f; // wählt int f(int) }; // 6. Cast auto p = static_cast<int(*)(int)>(f); // wählt int f(int) // 7. Template-Argument Templ<f> t; // wählt int f(int) // Verhindert "unused variable"-Warnungen wie durch [[maybe_unused]] [](...){}(pf, rf, mpf, foo, p, t); }
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| CWG 202 | C++98 |
konstanter Template-Argument war kein Kontext
für die Adressnahme einer überladenen Funktion |
ist es |
| CWG 250 | C++98 |
Funktions-Template-Spezialisierungen mit nicht abgeleiteten
Template-Argumenten wurden nicht aus dem Überladungssatz ausgewählt |
ebenfalls ausgewählt |
| CWG 1153 | C++98 | es war unklar, ob ein gegebener Funktionstyp mit dem Zieltyp übereinstimmt | klargestellt |
| CWG 1563 | C++11 |
es war unklar, ob die Listeninitialisierung ein Kontext
für die Adressnahme einer überladenen Funktion ist |
klargestellt |
Referenzen
- C++23-Standard (ISO/IEC 14882:2024):
-
- 12.3 Adresse überladener Funktion [over.over]
- C++20-Standard (ISO/IEC 14882:2020):
-
- 12.5 Adresse überladener Funktion [over.over]
- C++17-Standard (ISO/IEC 14882:2017):
-
- 16.4 Adresse überladener Funktion [over.over]
- C++14-Standard (ISO/IEC 14882:2014):
-
- 13.4 Adresse überladener Funktion [over.over]
- C++11-Standard (ISO/IEC 14882:2011):
-
- 13.4 Adresse überladener Funktion [over.over]
- C++98 Standard (ISO/IEC 14882:1998):
-
- 13.4 Adresse überladener Funktionen [over.over]