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

Met fin à la fonction actuelle et renvoie la valeur spécifiée (le cas échéant) à l'appelant.

Table des matières

Syntaxe

attr  (optionnel) return expression  (optionnel) ; (1)
attr  (optionnel) return braced-init-list ; (2) (depuis C++11)
attr  (optionnel) co_return expression  (optionnel) ; (3) (depuis C++20)
attr  (optionnel) co_return braced-init-list ; (4) (depuis C++20)
attr - (depuis C++11) séquence d'un nombre quelconque d' attributs
expression - expression , convertible en type de retour de la fonction
braced-init-list - liste d'initialisation entre accolades

Explication

1) Évalue l' expression , termine la fonction courante et retourne le résultat de l' expression à l'appelant, après conversion implicite vers le type de retour de la fonction. L' expression est optionnelle dans les fonctions dont le type de retour est (éventuellement qualifié cv) void , et interdite dans les constructeurs et les destructeurs.
2) Utilise copy-list-initialization pour construire la valeur de retour de la fonction.
3,4) Dans une coroutine, le mot-clé co_return doit être utilisé à la place de return pour le point de suspension final (voir coroutines pour plus de détails).

L' expression ou la liste d'initialisation entre accolades (depuis C++11) (le cas échéant) est appelée l' opérande de l'instruction return .

Il y a un point de séquence entre la copie-initialisation du résultat de l'appel de fonction et la destruction de tous les temporaires à la fin de expression .

(jusqu'en C++11)

La copie-initialisation du résultat de l'appel de fonction est séquencée avant la destruction de tous les temporaires à la fin de expression , qui, à son tour, est séquencée avant la destruction des variables locales du bloc englobant l'instruction return .

(depuis C++11)

Si le type de retour de la fonction est un type référence et qu'une instruction return (1,2) lie la référence retournée au résultat d'une expression temporaire , le programme est mal formé.

(depuis C++26)

Si le contrôle atteint la fin de

  • une fonction avec le type de retour (éventuellement qualifié cv) void ,
  • un constructeur,
  • un destructeur, ou
  • un bloc try de fonction pour une fonction avec le type de retour (éventuellement qualifié cv) void

sans rencontrer d'instruction return , return ; est exécuté.

Si le contrôle atteint la fin de la main function , return 0 ; est exécuté.

Sortir de la fin d'une fonction retournant une valeur, à l'exception de la main function et des coroutines spécifiques (depuis C++20) , sans instruction return est un comportement indéfini.

Dans une fonction retournant (éventuellement qualifié cv) void , l'instruction return avec expression peut être utilisée, si le type de l'expression est (éventuellement qualifié cv) void .

Si le type de retour d'une fonction est spécifié comme un type substitut , il sera déduit de la valeur de retour. Si decltype ( auto ) est utilisé, la déduction de type traite une expression qui peut être une entité comme une entité .

(depuis C++14)

Notes

Le retour par valeur peut impliquer la construction et la copie/déplacement d'un objet temporaire, à moins que copy elision ne soit utilisée. Plus précisément, les conditions pour la copie/le déplacement sont les suivantes :

Déplacement automatique depuis les variables locales et paramètres

L' expression est éligible au déplacement si c'est une expression d'identificateur (éventuellement entre parenthèses) qui désigne une variable de durée de stockage automatique dont le type est

  • un type objet non volatile
(depuis C++11)
  • ou une référence rvalue non volatile vers un type objet
(depuis C++20)

et cette variable est déclarée

  • dans le corps
  • ou comme paramètre

de la fonction ou expression lambda englobante la plus interne.

(depuis C++11)

Si l' expression est éligible au déplacement, la résolution de surcharge pour sélectionner le constructeur à utiliser pour l'initialisation de la valeur retournée ou, pour co_return , pour sélectionner la surcharge de promise. return_value ( ) (depuis C++20) est effectuée deux fois :

  • si la première résolution de surcharge a échoué
(depuis C++11)
(jusqu'à C++23)
  • ou si elle a réussi, mais n'a pas sélectionné le constructeur de déplacement (formellement, le premier paramètre du constructeur sélectionné n'était pas une référence rvalue vers le type (éventuellement qualifié cv) de l' expression )
(depuis C++11)
(jusqu'à C++20)
  • alors la résolution de surcharge est effectuée normalement, avec l' expression considérée comme une lvalue (elle peut donc sélectionner le constructeur de copie ).
(depuis C++11)
(jusqu'à C++23)

Si l' expression est éligible au déplacement, elle est traitée comme une xvalue (la résolution de surcharge peut donc sélectionner le constructeur de déplacement ).

(depuis C++23)

Élision de copie garantie

Si l' expression est une prvalue, l'objet résultat est initialisé directement par cette expression. Cela n'implique pas de constructeur de copie ou de déplacement lorsque les types correspondent (voir élision de copie ).

(depuis C++17)
Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_implicit_move 202207L (C++23) Déplacement implicite simplifié

Mots-clés

return , co_return

Exemple

#include <iostream>
#include <string>
#include <utility>
void fa(int i)
{
    if (i == 2)
        return;
    std::cout << "fa("<< i << ")\n";
} // retour implicite ;
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) est une expression void
}
int main()
{
    fa(1); // affiche son argument, puis retourne
    fa(2); // ne fait rien quand i == 2, retourne simplement
    int i = fb(5); // retourne 4
    i = fb(i);     // affiche son argument, retourne 2
    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. déplacement implicite
}
MoveOnly move_11(MoveOnly&& arg)
{
    return arg; // OK depuis C++20. déplacement implicite
}
MoveOnly&& move_23(MoveOnly&& arg)
{
    return arg; // OK depuis C++23. déplacement implicite
}

Sortie :

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

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement publié Comportement correct
CWG 1541 C++98 expression ne pouvait pas être omise si le type de retour est cv-qualifié void elle peut être omise
CWG 1579 C++11 le retour par constructeur de déplacement de conversion n'était pas autorisé recherche du constructeur de déplacement
de conversion activée
CWG 1885 C++98 l'ordonnancement de la destruction des variables automatiques n'était pas explicite règles d'ordonnancement ajoutées

Voir aussi

Documentation C pour return statement