Почему std :: any & amp; оператор = для ValueType не является условно noexcept?

Вопрос довольно прост.

Это объявление шаблонного оператора = для std::any:

template<typename ValueType>
any& operator=( ValueType&& rhs );

Я ожидаю, что это будет:

template<typename ValueType>
any& operator=( ValueType&& rhs ) noexcept(noexcept(std::declval<std::any>() = std::forward<ValueType>(std::declval<ValueType>()));

А именно, если вы можете скопировать-присвоить ValueType любому типу noexcept, то вы должны иметь возможность noexcept.

Может быть, я что-то упустил.

2

Решение

Буквальный ответ заключается в том, что такая спецификация будет рекурсивной (вы говорите, что noexcept если назначение noexcept).

Но, вероятно, более полезный ответ заключается в том, что с any возможно, придется выделить, вы могли бы действительно иметь noexcept назначение в случае, если decay_t<ValueType> является

  • достаточно мал (чтобы не требовалось распределение), и
  • не ходи конструктивно, и
  • nothrow конструируемый из ValueType

Единственный способ указать noexcept Условие потребовало бы, чтобы вы также указали, что означает «достаточно маленький» — что ограничит свободу реализации для сомнительной выгоды.

Стандартная библиотека обычно не использует условное noexcept — так почему бы это … исключение?

6

Другие решения

template<class T> any& operator=(T&& rhs);

[Any.assign] / 12 — Броски: Любое исключение, выброшенное выбранным конструктором VT.

Показанная вами перегрузка участвует только в разрешении перегрузки, если ValueType является копируемым, оставляя дверь открытой для копирования ValueType бросать во время std::any назначение.

Обратите внимание, что вы также показываете noexcept спецификация определяется в терминах той же самой операции, которая определяется.

1