Spec-Zone.ru › C++

return инструкция

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

Синтаксис

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

Пояснение

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

expression или braced-init-list(с C++11) (если есть) называется операндом инструкции return.

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

(до C++11)

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

(с C++11)

Если возвращаемый тип функции является ссылочным типом, а инструкция return (1,2) связывает возвращаемую ссылку с результатом временного выражения, программа некорректна.

(с C++26)

Если управление достигает конца

  • функции с типом возвращаемого значения (возможно, cv-квалифицированным) void,
  • конструктора,
  • деструктора или
  • блока try функции с типом возвращаемого значения (возможно, cv-квалифицированным) void

и при этом не встречает инструкцию return, выполняется return;.

Если управление достигает конца функции main, выполняется return 0;.

Достижение конца функции, возвращающей значение, без инструкции return приводит к неопределённому поведению, за исключением функции main и некоторых сопрограмм(с C++20).

В функции, возвращающей (возможно, cv-квалифицированный) void, можно использовать инструкцию return с expression, если тип выражения — (возможно, cv-квалифицированный) void.

Если возвращаемый тип функции задан как тип-заполнитель, он будет выведен из возвращаемого значения. При использовании decltype(auto) при выводе типа expression, которое может быть entity, рассматривается как entity.

(с C++14)

Примечания

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

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

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

  • неизменяемый объектный тип
(с C++11)
  • или rvalue-ссылку на объектный тип, не являющуюся volatile
(с C++20)

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

  • в теле
  • или в качестве параметра

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

(с C++11)

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

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

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

(с C++23)

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

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

(с C++17)
Макрос проверки поддержки возможностей Значение Стандарт Возможность
__cpp_implicit_move 202207L (C++23) Упрощённое неявное перемещение

Ключевые слова

return, co_return

Пример

#include <iostream>
#include <string>
#include <utility>

void fa(int i)
{
    if (i == 2)
        return;
    std::cout << "fa("<< i << ")\n";
} // implied return;

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) is a void expression
}

int main()
{
    fa(1); // prints its argument, then returns
    fa(2); // does nothing when i == 2, just returns
    
    int i = fb(5); // returns 4
    i = fb(i);     // prints its argument, returns 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. implicit move
}

MoveOnly move_11(MoveOnly&& arg)
{
    return arg; // OK since C++20. implicit move
}

MoveOnly&& move_23(MoveOnly&& arg)
{
    return arg; // OK since C++23. implicit move
}

Вывод:

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

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.

Отчёт об ошибке Применён к Опубликованное поведение Корректное поведение
CWG 1541 C++98 expression нельзя было опустить, если возвращаемый тип был cv-квалифицированным void его можно опустить
CWG 1579 C++11 возврат с помощью преобразующего конструктора перемещения был запрещён поиск преобразующего
конструктора перемещения разрешён
CWG 1885 C++98 порядок уничтожения автоматических переменных не был явно определён добавлены правила упорядочивания

См. также

  • устранение копирования
Документация по C для инструкции return

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/return

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API