noexcept specifier с конструкцией аргументов по умолчанию

Возьмем следующий пример кода:

void test(const Item& item = Item()) {
   ...
}

Предположим, что после того, как item передан функции, это не может выбраться.

Вопрос в том, что функция должна быть отмечена noexcept или noexcept(noexcept(Item()))?

IHMO, первый должен быть в порядке, но я не уверен. Цитата из стандарта была бы очень оценена!

Ответ 1

Аргументы по умолчанию - это ярлыки для вызывающего абонента. Итак, когда функция выполняется, конструкция уже завершена.

Таким образом, noexcept должно быть достаточно.

В стандарте [dcl.fct.default] указано:

Если в объявлении параметра указано условие инициализатора, это условие инициализатора используется как аргумент по умолчанию. Аргументы по умолчанию будут использоваться в вызовах, в которых отсутствуют конечные аргументы.

Пример: объявление void point(int = 3, int = 4); объявляет функцию, которая может быть вызвана с нулевым, одним или двумя аргументами типа int. Его можно вызвать любым из следующих способов: point(1,2); point(1); point(); Последние два вызова эквивалентны point(1,4) и point(3,4) соответственно.

Также есть примечание (в [intro.execution] Выполнение программы):

Подвыражения, связанные с оценкой аргументов по умолчанию (8.3.6), считаются создаваемыми в выражении, которое вызывает функцию, а не в выражении, которое определяет аргумент по умолчанию