return
statement
Termina la función actual y devuelve el valor especificado (si lo hay) al llamador.
Contenidos |
Sintaxis
attr
(opcional)
return
expresión
(opcional)
;
|
(1) | ||||||||
attr
(opcional)
return
lista-de-inicialización-entre-llaves
;
|
(2) | (desde C++11) | |||||||
attr
(opcional)
co_return
expresión
(opcional)
;
|
(3) | (desde C++20) | |||||||
attr
(opcional)
co_return
lista-de-inicialización-entre-llaves
;
|
(4) | (desde C++20) | |||||||
| attr | - | (since C++11) secuencia de cualquier número de atributos |
| expression | - | expresión , convertible al tipo de retorno de la función |
| braced-init-list | - | lista de inicializadores entre llaves |
Explicación
La expresión o lista-de-inicialización-entre-llaves (desde C++11) (si existe) se conoce como el operando de la sentencia return .
|
Existe un punto de secuencia entre la inicialización por copia del resultado de la llamada a la función y la destrucción de todos los temporales al final de la expresión . |
(hasta C++11) |
|
La inicialización por copia del resultado de la llamada a la función está secuenciada-antes de la destrucción de todos los temporales al final de la expresión , que, a su vez, está secuenciada-antes de la destrucción de las variables locales del bloque que encierra la sentencia return . |
(desde C++11) |
|
Si el tipo de retorno de la función es un tipo referencia y una sentencia return (1,2) vincula la referencia retornada al resultado de una expresión temporal , el programa está mal formado. |
(desde C++26) |
Si el control llega al final de
- una función con el tipo de retorno (posiblemente calificado cv) void ,
- un constructor,
- un destructor, o
- un bloque try de función para una función con el tipo de retorno (posiblemente calificado cv) void
sin encontrar una return statement, return ; se ejecuta.
Si el control alcanza el final de la
main
función
,
return
0
;
se ejecuta.
Salir del final de una función que retorna un valor, excepto la función
main
y ciertas
corrutinas
(desde C++20)
, sin una sentencia
return
es comportamiento indefinido.
En una función que retorna (posiblemente calificado con cv) void , la sentencia return con expresión puede ser utilizada, si el tipo de la expresión es (posiblemente calificado con cv) void .
|
Si el tipo de retorno de una función se especifica como un tipo de marcador de posición , será deducido a partir del valor de retorno. Si se utiliza decltype ( auto ) , la deducción de tipos trata una expresión que puede ser una entidad como una entidad . |
(desde C++14) |
Notas
Retornar por valor puede involucrar la construcción y copia/traslado de un objeto temporal, a menos que se utilice copy elision . Específicamente, las condiciones para copia/traslado son las siguientes:
Movimiento automático desde variables locales y parámetrosLa expresión es elegible para movimiento si es una expresión de identificador (posiblemente entre paréntesis) que nombra una variable de duración de almacenamiento automático cuyo tipo es
|
(desde C++11) |
|
(desde C++20) |
|
y esa variable está declarada
de la función o expresión lambda envolvente más interna. |
(desde C++11) |
|
Si la expresión es elegible para movimiento, la resolución de sobrecarga para seleccionar el constructor a usar para la inicialización del valor devuelto o, para co_return , para seleccionar la sobrecarga de promise. return_value ( ) (desde C++20) se realiza dos veces :
|
(desde C++11)
(hasta C++23) |
|
(desde C++11)
(hasta C++20) |
|
(desde C++11)
(hasta C++23) |
|
Si la expresión es elegible para movimiento, se trata como un valor x (por lo tanto la resolución de sobrecarga puede seleccionar el constructor de movimiento ). |
(desde C++23) |
Eliminación de copia garantizadaSi la expresión es un valor pr, el objeto resultado se inicializa directamente por esa expresión. Esto no implica un constructor de copia o movimiento cuando los tipos coinciden (ver eliminación de copia ). |
(desde C++17) |
| Macro de prueba de características | Valor | Std | Característica |
|---|---|---|---|
__cpp_implicit_move
|
202207L
|
(C++23) | Movimiento implícito más simple |
Palabras clave
Ejemplo
#include <iostream> #include <string> #include <utility> void fa(int i) { if (i == 2) return; std::cout << "fa("<< i << ")\n"; } // retorno implícito; 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) es una expresión void } int main() { fa(1); // imprime su argumento, luego retorna fa(2); // no hace nada cuando i == 2, solo retorna int i = fb(5); // retorna 4 i = fb(i); // imprime su argumento, retorna 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. movimiento implícito } MoveOnly move_11(MoveOnly&& arg) { return arg; // OK desde C++20. movimiento implícito } MoveOnly&& move_23(MoveOnly&& arg) { return arg; // OK desde C++23. movimiento implícito }
Salida:
fa(1) fb(4) i = 2 fc(~).second = 7 fa(10)
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.
| DR | Se aplica a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 1541 | C++98 | expresión no podía omitirse si el tipo de retorno es cv-calificado void | puede omitirse |
| CWG 1579 | C++11 | no se permitía el retorno mediante constructor de movimiento de conversión |
búsqueda de constructor de movimiento
de conversión habilitada |
| CWG 1885 | C++98 | la secuenciación de la destrucción de variables automáticas no era explícita | reglas de secuenciación añadidas |
Véase también
|
Documentación de C
para
return
statement
|