Namespaces
Variants

Address of an overloaded function

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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 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 Spezialisierung (falls vorhanden), die durch Template-Argumentableitung für jede benannte Funktionsvorlage generiert wird, wird ebenfalls zu S hinzugefü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.

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

  • Alle Funktionen mit zugehörigen Constraints , die nicht erfüllt sind, werden aus der S entfernt.
(seit C++20)
  • Wenn mehr als eine Funktion in S verbleibt, werden alle Funktions-Templatespezialisierungen in S eliminiert, falls S auch eine Nicht-Template-Funktion enthält.
(since C++20)
  • Jede gegebene Funktionstemplatespezialisierung spec wird eliminiert, falls S eine 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]