Пространства имён
Варианты
Действия

Оператор return

Материал из cppreference.com
< cpp‎ | language
 
 
 
Инструкции
Метки
метка : оператор
Операторы выражений
выражение ;
Составные операторы
{ оператор... }
Операторы выбора
if
switch
Операторы итерирования
while
do-while
for
диапазонный for(C++11)
Операторы переходов
break
continue
return
goto
Операторы объявления
объявление ;
Блоки try
try составной-операторпоследовательность-обработчиков
Транзакционная память
synchronized, atomic_commit, и т.д. (ТС TM)
 

Завершает текущую функцию и возвращает указанное значение (если есть) вызывающей стороне.

Содержание

[править]Синтаксис

атрибуты (необязательно)returnвыражение (необязательно); (1)
атрибуты (необязательно)returnсписок-инициализации-в-фигурных-скобках; (2) (начиная с C++11)
атрибуты (необязательно)co_returnвыражение (необязательно); (3) (начиная с C++20)
атрибуты (необязательно)co_returnсписок-инициализации-в-фигурных-скобках; (4) (начиная с C++20)
атрибуты(начиная с C++11) последовательность любого количества атрибутов
выражениевыражение, преобразуемое в возвращаемый тип функции
список-инициализации-в-фигурных-скобках заключённый-в-фигурные-скобки список инициализаторов и другие списки-инициализации-в-фигурных-скобках

[править]Объяснение

1) Вычисляет выражение, завершает текущую функцию и возвращает результат выражения вызывающему объекту после неявного преобразования в возвращаемый тип функции. выражение является необязательным в функциях, тип возвращаемого значения которых (возможно, cv-квалифицированный) void, и запрещено в конструкторах и деструкторах.
2) Использует копирование-списка-инициализации для создания возвращаемого значения функции.
3,4) В сопрограмме ключевое слово co_return должно использоваться вместо return для конечной точки приостановки (подробности смотрите в сопрограммах).

Существуют точки последовательности между инициализацией копированием результата вызова функции и уничтожением всех временных объектов в конце выражения.

(до 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)

Возврат по значению может включать создание и копирование/перемещение временного объекта, если только не используется пропуск копирования. В частности, условия для копирования/перемещения следующие:

Автоматическое перемещение локальных переменных и параметров

выражение является подходящим для перемещения, если оно представляет собой (возможно, в скобках) выражение-идентификатор, которое именует переменную с автоматической длительностью хранения, тип которой

  • не volatile тип объекта
  • или не volatile ссылка rvalue на тип объекта
(начиная с C++20)

и эта переменная объявлена

  • в теле или
  • как параметр
самой внутренней объемлющей функции или лямбда-выражения.

Если выражение подходит для перемещения, разрешение перегрузки для выбора конструктора, который будет использоваться для инициализации возвращаемого значения или, для co_return, для выбора promise.return_value()(начиная с C++20) выполняется дважды:

  • если первое разрешение перегрузки не удалось или
  • удалось, но не был выбран конструктор перемещения (формально первый параметр выбранного конструктора не был ссылкой rvalue на (возможно, cv-квалифицированный) тип выражения)
(до C++20)
  • затем разрешение перегрузки выполняется как обычно, при этом выражение рассматривается как lvalue (поэтому может быть выбран конструктор копирования).
(до C++23)

Если выражение подходит для перемещения, оно обрабатывается как значение xvalue (таким образом, разрешение перегрузки может выбрать конструктор перемещения).

(начиная с C++23)
(начиная с C++11)

Гарантированный пропуск копирования

Если выражение является значением prvalue, объект результата инициализируется непосредственно этим выражением. Когда типы совпадают это не требует конструктора копирования или перемещения (смотрите пропуск копирования).

(начиная с C++17)
Макрос Тестирования функциональностиЗначениеСтандартФункциональность
__cpp_implicit_move202207L(C++23)Более простое неявное перемещение

[править]Ключевые слова

return, co_return

[править]Пример

#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
close