Adresse einer überladenen Funktion
Neben Funktionsaufrufausdrücken, bei denen die Überladungsauflösung stattfindet, kann der Name einer überladenen Funktion in den folgenden 7 Kontexten auftreten
| Kontext | Ziel |
|---|---|
| Initialisierer in einer Deklaration eines Objekts oder einer Referenz | das zu initialisierende Objekt oder die zu initialisierende Referenz |
| auf der rechten Seite eines Zuweisungsausdrucks | die linke Seite der Zuweisung |
| als Argument eines Funktionsaufrufs | der Funktionsparameter |
| als Argument eines benutzerdefinierten Operators | der Operatorparameter |
die return-Anweisung |
der Rückgabewert einer Funktion oder Konvertierung |
Argument eines expliziten Casts oder static_cast |
der entsprechende Cast |
| Nicht-Typ-Template-Argument | der entsprechende Template-Parameter |
In jedem Kontext kann der Name einer überladenen Funktion mit dem Adressoperator & vorangestellt und in eine redundante Klammerung eingeschlossen werden.
|
Wenn der Zieltyp einen Platzhaltertyp enthält, wird die Platzhaltertyp-Ableitung durchgeführt, und die folgende Beschreibung verwendet den abgeleiteten Typ als Zieltyp. |
(seit C++26) |
Inhalt |
[bearbeiten] Auswahl von Funktionen
Wenn die Adresse einer überladenen Funktion genommen wird, wird aus der Überladungsmenge, auf die sich der Name der überladenen Funktion bezieht, eine Menge S von Funktionen ausgewählt
- Wenn kein Ziel vorhanden ist, werden alle nicht-templatisierten Funktionen mit diesem Namen ausgewählt.
- Andernfalls wird eine nicht-templatisierte Funktion mit dem Typ
Ffür den FunktionstypFTdes Zieltyps ausgewählt, wennF(nach möglicher Anwendung der Funktionszeigerkonvertierung)(seit C++17) identisch mitFTist.[1] - Die durch Template-Argument-Ableitung für jede benannte Funktionstemplate generierte Spezialisierung (falls vorhanden) wird ebenfalls zu
Shinzugefügt.
Wenn das Ziel vom Typ Funktionzeiger oder Referenz auf Funktion ist, darf S nur nicht-Mitgliedfunktionen, explizite Objekt-Mitgliedfunktionen(seit C++23) und statische Mitgliedfunktionen enthalten. Wenn das Ziel vom Typ Zeiger-auf-Mitgliedfunktion ist, darf S nur implizite Objekt-Mitgliedfunktionen enthalten.
- ↑ Mit anderen Worten, die Klasse, deren Mitglied die Funktion ist, wird ignoriert, wenn der Zieltyp ein Zeiger-auf-Mitgliedfunktionstyp ist.
[bearbeiten] Eliminierung von Funktionen
Nachdem die Menge S gebildet wurde, werden Funktionen in der folgenden Reihenfolge eliminiert:
|
(seit C++20) |
- Wenn mehr als eine Funktion in
Sverbleibt, werden alle Funktionstemplate-Spezialisierungen inSeliminiert, wennSauch eine nicht-templatisierte Funktion enthält.
|
(seit C++20) |
- Eine gegebene Funktionstemplate-Spezialisierung spec wird eliminiert, wenn
Seine zweite Funktionstemplate-Spezialisierung enthält, deren Funktionstemplate spezialisierter ist als das Funktionstemplate von spec.
Nach solchen Eliminierungen (falls vorhanden) sollte genau eine ausgewählte Funktion in S verbleiben. Andernfalls ist das Programm ill-formed.
[bearbeiten] 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. initialization int (*pf)(double) = f; // selects int f(double) int (&rf)(int) = f; // selects int f(int) int (Foo::*mpf)(int) = &Foo::mf; // selects int mf(int) // 2. assignment pf = nullptr; pf = &f; // selects int f(double) // 3. function argument g(f, f); // selects int f(int) for the 1st argument // and int f(double) for the second // 4. user-defined operator Emp{} << f; //selects int f(double) // 5. return value auto foo = []() -> int (*)(int) { return f; // selects int f(int) }; // 6. cast auto p = static_cast<int(*)(int)>(f); // selects int f(int) // 7. template argument Templ<f> t; // selects int f(int) // prevent “unused variable” warnings as if by [[maybe_unused]] [](...){}(pf, rf, mpf, foo, p, t); }
[bearbeiten] Defect reports
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 202 | C++98 | nicht-typgebundenes Template-Argument war kein Kontext der Adressnahme einer überladenen Funktion |
sie ist |
| CWG 250 | C++98 | Funktionstemplate-Spezialisierungen, die mit nicht-deduzierten Template-Argumenten generiert wurden, wurden nicht aus der Überladungsmenge ausgewählt |
auch ausgewählt |
| CWG 1153 | C++98 | es war unklar, ob ein gegebener Funktionstyp mit dem Zieltyp übereinstimmte | wurde klargestellt |
| CWG 1563 | C++11 | es war unklar, ob Listeninitialisierung ein Kontext ist der Adressnahme einer überladenen Funktion |
wurde klargestellt |
[bearbeiten] Referenzen
- C++23 Standard (ISO/IEC 14882:2024)
- 12.3 Adresse einer überladenen Funktion [over.over]
- C++20 Standard (ISO/IEC 14882:2020)
- 12.5 Adresse einer überladenen Funktion [over.over]
- C++17 Standard (ISO/IEC 14882:2017)
- 16.4 Adresse einer überladenen Funktion [over.over]
- C++14 Standard (ISO/IEC 14882:2014)
- 13.4 Adresse einer überladenen Funktion [over.over]
- C++11 Standard (ISO/IEC 14882:2011)
- 13.4 Adresse einer überladenen Funktion [over.over]
- C++98 Standard (ISO/IEC 14882:1998)
- 13.4 Adresse einer überladenen Funktion [over.over]