Оператор return
Завершает текущую функцию и возвращает указанное значение (если есть) вызывающей стороне.
Содержание |
[править]Синтаксис
атрибуты (необязательно)return выражение (необязательно); | (1) | ||||||||
атрибуты (необязательно)return список-инициализации-в-фигурных-скобках; | (2) | (начиная с C++11) | |||||||
атрибуты (необязательно)co_return выражение (необязательно); | (3) | (начиная с C++20) | |||||||
атрибуты (необязательно)co_return список-инициализации-в-фигурных-скобках; | (4) | (начиная с C++20) | |||||||
атрибуты | — | (начиная с C++11) последовательность любого количества атрибутов |
выражение | — | выражение, преобразуемое в возвращаемый тип функции |
список-инициализации-в-фигурных-скобках | — | заключённый-в-фигурные-скобки список инициализаторов и другие списки-инициализации-в-фигурных-скобках |
[править]Объяснение
Существуют точки последовательности между инициализацией копированием результата вызова функции и уничтожением всех временных объектов в конце выражения. | (до C++11) |
Инициализация копированием результата вызова функции упорядочено до уничтожения всех временных переменных в конце выражения, что, в свою очередь, упорядочено до уничтожения локальных переменных блока, содержащего оператор return. | (начиная с C++11) |
[править]Примечание
Если управление достигает конца
- функции с возвращаемым типом (возможно, cv-квалифицированным) void,
- конструктора,
- деструктора, или
- try-блока функции для функции с возвращаемым типом (возможно cv-квалифицированным) void
не встретив оператора return, выполняется, return;.
Если управление достигает конца функции main, выполняется return0;.
Достижение конца функции, возвращающей значение, кроме 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)return4;std::cout<<"fb("<< i <<")\n";return2;} std::pair<std::string, int> fc(constchar* 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);// печатает свой аргумент, возвращает 2std::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 |