Оператор return
Завершает текущую функцию и возвращает указанное значение (если есть) вызывающей стороне.
Синтаксис
атрибуты (необязательно) return выражение (необязательно) ;
|
(1) | ||||||||
атрибуты (необязательно) return список-инициализации-в-фигурных-скобках ;
|
(2) | (начиная с C++11) | |||||||
атрибуты (необязательно) co_return выражение (необязательно) ;
|
(3) | (начиная с C++20) | |||||||
атрибуты (необязательно) co_return список-инициализации-в-фигурных-скобках ;
|
(4) | (начиная с C++20) | |||||||
| атрибуты | — | (начиная с C++11) последовательность любого количества атрибутов |
| выражение | — | выражение, преобразуемое в возвращаемый тип функции |
| список-инициализации-в-фигурных-скобках | — | заключённый-в-фигурные-скобки список инициализаторов и другие списки-инициализации-в-фигурных-скобках |
Объяснение
void, и запрещено в конструкторах и деструкторах.|
Существуют точки последовательности между инициализацией копированием результата вызова функции и уничтожением всех временных объектов в конце выражения. |
(до C++11) |
|
Инициализация копированием результата вызова функции упорядочено до уничтожения всех временных переменных в конце выражения, что, в свою очередь, упорядочено до уничтожения локальных переменных блока, содержащего оператор return. |
(начиная с C++11) |
Примечание
Если управление достигает конца
- функции с возвращаемым типом (возможно, cv-квалифицированным)
void, - конструктора,
- деструктора, или
- try-блока функции для функции с возвращаемым типом (возможно cv-квалифицированным)
void
не встретив оператора return, выполняется, return;.
Если управление достигает конца функции main, выполняется return 0;.
Достижение конца функции, возвращающей значение, кроме main и специфической coroutines (начиная с C++20), без оператора return, является неопределённым поведением.
В функции, возвращающей (возможно, cv-квалифицированной) void, можно использовать оператор return с выражением, если тип выражения (возможно, cv-квалифицированный) void.
|
Если тип возвращаемого значения функции указан как тип заполнитель, он будет выведен из возвращаемого значения. |
(начиная с C++14) |
Возврат по значению может включать создание и копирование/перемещение временного объекта, если только не используется пропуск копирования. В частности, условия для копирования/перемещения следующие:
Автоматическое перемещение локальных переменных и параметроввыражение является подходящим для перемещения, если оно представляет собой (возможно, в скобках) выражение-идентификатор, которое именует переменную с автоматической длительностью хранения, тип которой
и эта переменная объявлена
|
(начиная с C++11) |
Гарантированный пропуск копированияЕсли выражение является значением prvalue, объект результата инициализируется непосредственно этим выражением. Когда типы совпадают это не требует конструктора копирования или перемещения (смотрите пропуск копирования). |
(начиная с C++17) |
| Макрос Тестирования функциональности | Значение | Стандарт | Функциональность |
|---|---|---|---|
__cpp_implicit_move |
202207L |
(C++23) | Более простое неявное перемещение |
Ключевые слова
Пример
#include <iostream>
#include <string>
#include <utility>
void fa(int i)
{
if (i == 2)
return;
std::cout << "fa("<< i << ")\n";
} // подразумеваемый возврат;
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) является void выражением
}
int main()
{
fa(1); // печатает свой аргумент, затем возвращается
fa(2); // ничего не делает, когда i == 2, просто возвращается
int i = fb(5); // возвращает 4
i = fb(i); // печатает свой аргумент, возвращает 2
std::cout << "i = " << i << '\n'
<< "fc(~).second = " << fc("Привет", 7).second << '\n';
fd();
}
Вывод:
fa(1)
fb(4)
i = 2
fc(~).second = 7
fa(10)
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| CWG 1541 | C++98 | выражение нельзя опускать, если тип возвращаемого значения cv-квалифицированный void
|
его можно опустить |
| CWG 1579 | C++11 | возврат преобразующим конструктором перемещения не разрешён |
поиск преобразующего конструктора перемещения доступен |
| CWG 1885 | C++98 | последовательность уничтожения автоматических переменных не была явной |
добавлены правила последовательности |
Смотрите также
Документация C по Оператор
return |