Почему std :: any & operator = для ValueType не является условно noexcept? - PullRequest
0 голосов
/ 25 декабря 2018

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

Это объявление шаблонного оператора = для 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 ]

0 голосов
/ 25 декабря 2018

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

[any.assign] / 12 - Выдает: Любое исключение, выбрасываемое выбранным конструктором VT.

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

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

0 голосов
/ 25 декабря 2018

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

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

  • достаточно мало (чтобы не нуждаться в распределении), и
  • nothrow move constructible и
  • nothrow constructible from ValueType

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

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

...