Namespaces
Variants

return statement

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
goto - return
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

Beendet die aktuelle Funktion und gibt den angegebenen Wert (falls vorhanden) an den Aufrufer zurück.

Inhaltsverzeichnis

Syntax

attr  (optional) return expression  (optional) ; (1)
attr  (optional) return braced-init-list ; (2) (seit C++11)
attr  (optional) co_return expression  (optional) ; (3) (seit C++20)
attr  (optional) co_return braced-init-list ; (4) (seit C++20)
attr - (since C++11) Folge beliebig vieler Attribute
expression - Ausdruck , konvertierbar in den Rückgabetyp der Funktion
braced-init-list - in geschweiften Klammern eingeschlossene Initialisiererliste

Erklärung

1) Wertet den Ausdruck aus, beendet die aktuelle Funktion und gibt das Ergebnis des Ausdrucks an den Aufrufer zurück, nach impliziter Konvertierung in den Funktion-Rückgabetyp. Der Ausdruck ist optional in Funktionen, deren Rückgabetyp (möglicherweise cv-qualifiziert) void ist, und unzulässig in Konstruktoren und Destruktoren.
2) Verwendet copy-list-initialization zur Konstruktion des Rückgabewerts der Funktion.
3,4) In einer Coroutine muss das Schlüsselwort co_return anstelle von return für den endgültigen Suspendierungspunkt verwendet werden (siehe Coroutines für Details).

Der Ausdruck oder die braced-init-list (seit C++11) (falls vorhanden) wird als Operand der return -Anweisung bezeichnet.

Es gibt einen Sequenzpunkt zwischen der Kopierinitialisierung des Ergebnisses des Funktionsaufrufs und der Zerstörung aller Temporärobjekte am Ende des Ausdrucks .

(bis C++11)

Die Kopierinitialisierung des Ergebnisses des Funktionsaufrufs ist sequenced-before der Zerstörung aller Temporärobjekte am Ende des Ausdrucks , was wiederum sequenced-before der Zerstörung der lokalen Variablen des Blocks ist, der die return -Anweisung umschließt.

(seit C++11)

Wenn der Rückgabetyp der Funktion ein Referenztyp ist und eine return -Anweisung (1,2) die zurückgegebene Referenz an das Ergebnis eines temporären Ausdrucks bindet, ist das Programm fehlerhaft.

(seit C++26)

Wenn die Steuerung das Ende von

  • eine Funktion mit dem Rückgabetyp (möglicherweise cv-qualifiziert) void ,
  • ein Konstruktor,
  • ein Destruktor, oder
  • ein Funktion try Block für eine Funktion mit dem Rückgabetyp (möglicherweise cv-qualifiziert) void

ohne auf eine return -Anweisung zu stoßen, wird return ; ausgeführt.

Wenn die Steuerung das Ende der main -Funktion erreicht, wird return 0 ; ausgeführt.

Das Verlassen des Endes einer wertrückgebenden Funktion, außer der main -Funktion und spezifischen Coroutinen (seit C++20) , ohne eine return -Anweisung ist undefiniertes Verhalten.

In einer Funktion, die (möglicherweise cv-qualifiziertes) void zurückgibt, kann die return -Anweisung mit Ausdruck verwendet werden, wenn der Ausdruckstyp (möglicherweise cv-qualifiziert) void ist.

Wenn der Rückgabetyp einer Funktion als ein Platzhaltertyp spezifiziert wird, wird er vom Rückgabewert abgeleitet . Wenn decltype ( auto ) verwendet wird, behandelt die Typableitung einen Ausdruck , der eine Entität sein kann, als eine Entität .

(seit C++14)

Hinweise

Die Rückgabe als Wert kann die Konstruktion und Kopie/Verschiebung eines temporären Objekts beinhalten, es sei denn, Copy Elision wird verwendet. Insbesondere gelten folgende Bedingungen für Kopie/Verschiebung:

Automatisches Verschieben von lokalen Variablen und Parametern

Der Ausdruck ist verschiebequalifiziert , wenn es sich um einen (möglicherweise in Klammern gesetzten) Identifikatorausdruck handelt, der eine Variable mit automatischer Speicherdauer bezeichnet, deren Typ

  • ein nicht-flüchtiger Objekttyp ist
(seit C++11)
  • oder ein nicht-flüchtiger Rvalue-Referenztyp auf Objekttyp ist
(seit C++20)

und diese Variable deklariert ist

  • im Rumpf
  • oder als Parameter

der innersten umschließenden Funktion oder Lambda-Expression.

(seit C++11)

Wenn der Ausdruck verschiebequalifiziert ist, wird die Überlagerungsauflösung zur Auswahl des Konstruktors für die Initialisierung des Rückgabewerts oder, für co_return , zur Auswahl der Überladung von promise. return_value ( ) (seit C++20) zweimal durchgeführt:

  • wenn die erste Überlagerungsauflösung fehlschlug
(seit C++11)
(bis C++23)
  • oder sie erfolgreich war, aber nicht den Verschiebekonstruktor auswählte (formal war der erste Parameter des gewählten Konstruktors keine Rvalue-Referenz auf den (möglicherweise cv-qualifizierten) Typ von Ausdruck )
(seit C++11)
(bis C++20)
  • dann wird die Überlagerungsauflösung wie üblich durchgeführt, wobei Ausdruck als Lvalue betrachtet wird (sodass er den Kopierkonstruktor auswählen kann).
(seit C++11)
(bis C++23)

Wenn der Ausdruck verschiebequalifiziert ist, wird er als Xvalue behandelt (sodass die Überlagerungsauflösung den Verschiebekonstruktor auswählen kann).

(seit C++23)

Garantierte Kopierelision

Wenn Ausdruck ein Prvalue ist, wird das Ergebnisobjekt direkt durch diesen Ausdruck initialisiert. Dies beinhaltet keinen Kopier- oder Verschiebekonstruktor, wenn die Typen übereinstimmen (siehe Kopierelision ).

(seit C++17)
Feature-Test-Makro Wert Std Feature
__cpp_implicit_move 202207L (C++23) Vereinfachtes implizites Verschieben

Schlüsselwörter

return , co_return

Beispiel

#include <iostream>
#include <string>
#include <utility>
void fa(int i)
{
    if (i == 2)
        return;
    std::cout << "fa("<< i << ")\n";
} // implizite Rückgabe;
int fb(int i)
{
    if (i > 4)
        return 4;
    std::cout << "fb(" << i << ")\n";
    return 2;
}
std::pair<std::string, int> fc(const char* p, int x)
{
    return {p, x};
}
void fd()
{
    return fa(10); // fa(10) ist ein void-Ausdruck
}
int main()
{
    fa(1); // gibt Argument aus, dann Rückgabe
    fa(2); // macht nichts wenn i == 2, nur Rückgabe
    int i = fb(5); // gibt 4 zurück
    i = fb(i);     // gibt Argument aus, gibt 2 zurück
    std::cout << "i = " << i << '\n'
              << "fc(~).second = " << fc("Hello", 7).second << '\n';
    fd();
}
struct MoveOnly
{
    MoveOnly() = default;
    MoveOnly(MoveOnly&&) = default;
};
MoveOnly move_11(MoveOnly arg)
{
    return arg; // OK. impliziter Move
}
MoveOnly move_11(MoveOnly&& arg)
{
    return arg; // OK seit C++20. impliziter Move
}
MoveOnly&& move_23(MoveOnly&& arg)
{
    return arg; // OK seit C++23. impliziter Move
}

Ausgabe:

fa(1)
fb(4)
i = 2
fc(~).second = 7
fa(10)

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 1541 C++98 expression konnte nicht weggelassen werden, wenn der Rückgabetyp cv-qualifiziert void ist kann weggelassen werden
CWG 1579 C++11 Rückgabe durch konvertierenden Move-Konstruktor war nicht erlaubt Suche nach konvertierendem Move-
Konstruktor aktiviert
CWG 1885 C++98 Reihenfolge der Zerstörung automatischer Variablen war nicht explizit Reihenfolgeregeln hinzugefügt

Siehe auch

C-Dokumentation für return Anweisung