Funktionen
Funktionen sind C++-Entitäten, die eine Sequenz von Anweisungen (einen Funktionsrumpf) mit einem Namen und einer Liste von null oder mehr Funktionsparametern assoziieren.
// function name: "isodd" // parameter list has one parameter, with name "n" and type int // the return type is bool bool isodd(int n) { // the body of the function begins return n % 2; } // the body of the function ends
Wenn eine Funktion aufgerufen wird, z. B. in einem Funktionsaufrufausdruck, werden die Parameter aus den Argumenten (entweder am Aufrufort bereitgestellt oder standardmäßig gesetzt) initialisiert und die Anweisungen im Funktionsrumpf ausgeführt. Wenn die Parameterliste mit ... endet, können der Funktion zusätzliche Argumente übergeben werden. Eine solche Funktion wird als variadische Funktion bezeichnet.
int main() { for (int arg : {-3, -2, -1, 0, 1, 2, 3}) std::cout << isodd(arg) << ' '; // isodd called 7 times, each // time n is copy-initialized from arg }
Nicht qualifizierte Funktionsnamen in Funktionsaufrufausdrücken werden mit einem zusätzlichen Regelwerk durchsucht, das als „Argument-abhängige Suche“ (ADL) bezeichnet wird.
Eine Funktion kann durch Rückgabe oder durch Auslösung einer Ausnahme beendet werden.
|
Eine Funktion kann eine Coroutine sein, in diesem Fall kann sie die Ausführung unterbrechen, um später fortgesetzt zu werden. |
(seit C++20) |
Eine Funktionsdeklaration kann in jedem Geltungsbereich erscheinen, aber eine Funktionsdefinition kann nur im Namespace-Geltungsbereich oder, für Member- und Friend-Funktionen, im Klassen-Geltungsbereich erscheinen. Eine Funktion, die in einem Klassenkörper ohne Friend-Spezifizierer deklariert wird, ist eine Klassen-Memberfunktion. Solche Funktionen haben viele zusätzliche Eigenschaften, siehe Memberfunktionen für Details.
Funktionen sind keine Objekte: Es gibt keine Arrays von Funktionen und Funktionen können nicht per Wert übergeben oder von anderen Funktionen zurückgegeben werden. Zeiger und Referenzen auf Funktionen (außer für die main-Funktion und die meisten Standardbibliotheksfunktionen(seit C++20)) sind erlaubt und können dort verwendet werden, wo diese Funktionen selbst nicht verwendet werden können. Daher sagen wir, dass diese Funktionen „adressierbar“ sind.
Jede Funktion hat einen Typ, der aus dem Rückgabetyp der Funktion, den Typen aller Parameter (nach Array-zu-Zeiger- und Funktions-zu-Zeiger-Transformationen, siehe Parameterliste), ob die Funktion noexcept ist oder nicht(seit C++17) und, für nicht-statische Memberfunktionen, CV-Qualifizierung und Ref-Qualifizierung(seit C++11) besteht. Funktionstypen haben auch eine Sprachverknüpfung. Es gibt keine CV-qualifizierten Funktionstypen (nicht zu verwechseln mit den Typen von CV-qualifizierten Funktionen wie int f() const; oder Funktionen, die CV-qualifizierte Typen zurückgeben, wie z. B. std::string const f();). Jeder CV-Qualifizierer wird ignoriert, wenn er zu einem Alias für einen Funktionstyp hinzugefügt wird.
Mehrere Funktionen im selben Geltungsbereich können denselben Namen haben, solange sich ihre Parameterlisten und, für nicht-statische Memberfunktionen, CV/Ref(seit C++11)-Qualifizierungen unterscheiden. Dies ist als Funktionsüberladung bekannt. Funktionsdeklarationen, die sich nur im Rückgabetyp und der noexcept-Spezifikation(seit C++17) unterscheiden, können nicht überladen werden. Die Adresse einer überladenen Funktion wird anders bestimmt.
|
C++ implementiert anonyme Funktionen mithilfe von Lambda-Ausdrücken. |
(seit C++11) |
[bearbeiten] Funktionsobjekte
Neben Funktions-Lvalues unterstützt der Funktionsaufrufausdruck Zeiger auf Funktionen und jeden Wert vom Klassentyp, der den Funktionsaufrufoperator überlädt oder in einen Funktionszeiger konvertierbar ist (einschließlich Lambda-Ausdrücken)(seit C++11). Zusammen sind diese Typen als FunctionObjects bekannt und werden allgegenwärtig in der C++-Standardbibliothek verwendet, siehe z. B. die Verwendungen von BinaryPredicate und Compare.
Die Standardbibliothek stellt auch eine Reihe vordefinierter Funktionsobjekt-Vorlagen sowie Methoden zur Komposition neuer Vorlagen bereit (einschließlich std::less, std::mem_fn, std::bind, std::function(seit C++11), std::not_fn(seit C++17), std::bind_front(seit C++20), std::bind_back, std::move_only_function(seit C++23), std::copyable_function und std::function_ref(seit C++26)).