Namensräume
Varianten
Aktionen

Adresse einer überladenen Funktion

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

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 F für den Funktionstyp FT des Zieltyps ausgewählt, wenn F (nach möglicher Anwendung der Funktionszeigerkonvertierung)(seit C++17) identisch mit FT ist.[1]
  • Die durch Template-Argument-Ableitung für jede benannte Funktionstemplate generierte Spezialisierung (falls vorhanden) wird ebenfalls zu S hinzugefü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.

  1. 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:

  • Alle Funktionen mit zugehörigen Constraints, die nicht erfüllt sind, werden aus S eliminiert.
(seit C++20)
  • Wenn mehr als eine Funktion in S verbleibt, werden alle Funktionstemplate-Spezialisierungen in S eliminiert, wenn S auch eine nicht-templatisierte Funktion enthält.
(seit C++20)
  • Eine gegebene Funktionstemplate-Spezialisierung spec wird eliminiert, wenn S eine 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]