Что-нибудь мешает std :: option :: value_or () быть условно noexcept? - PullRequest
0 голосов
/ 03 мая 2018

Вот определение value_or() из стандарта C ++ 17:

template <class U> constexpr T value_or(U&& v) const&;

Эффекты: Эквивалент:

return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));

Примечания: Если is_copy_constructible_v<T> && is_convertible_v<U&&, T> равно false, программа некорректна.

(перегрузка по значению аналогична)

Эффект value_or описывается как эквивалент return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));

operator bool - это noexcept. operator* - это , а не noexcept (даже если он не генерирует ошибку, возможно, потому что он все равно может потерпеть неудачу с UB, если используется, если необязательное значение не содержит значения). Однако мы гарантированно никогда не будем пытаться вернуть содержащееся в нем значение, если только оно у нас не будет.

Так что value_or нельзя объявить noexcept, учитывая is_nothrow_copy_constructible<T> && noexcept(static_cast<T>(std::forward<U>(v)))?

1 Ответ

0 голосов
/ 03 мая 2018

используется крайне редко в стандарте . Это единственный барьер.


В то время как это отвечает на вопрос, следующий вопрос - «почему это используется экономно». Это дополнительная информация, которая может оказаться полезной; если бы это было ядром ответа, я бы включил больше цитат вместо ссылок. Бумажные номера должны пережить конкретные гиперссылки, которые я использую, так что это так.

N3279 является заключением дискуссии о noexcept. По сути, все, что имеет узкий контракт (может иметь UB) и не является движением ctor или dtor, никогда не помечается как noexcept.

Вот рекомендации:

Принятые руководящие принципы

  • Никакой деструктор библиотеки не должен бросать. Они должны использовать неявно предоставленную (не генерирующую) спецификацию исключений.
  • Каждая библиотечная функция, имеющая широкий контракт, который, как соглашается LWG, не может выдать, должна быть помечена как безусловно noexcept.
  • Если библиотечная функция подкачки, оператор перемещения или конструктора перемещения является условно-широкой (т. Е. Может быть доказано, что она не выбрасывает с помощью оператора noexcept), то она должна быть помечена как условно noexcept. Никакая другая функция не должна использовать условную спецификацию noexcept.
  • Библиотечные функции, разработанные для совместимости с кодом «C» (например, средство атомарного анализа), могут быть помечены как безоговорочные noexcept.

Я не участвовал в обсуждении, но в основном идея заключается в том, что компилятор может добавлять исключения к этим методам.

Я считаю, что это называется правилом Лакоса. Чтобы изменить это, возьмите это с комитетом.

N3248 - бумага, в которой возникли проблемы без исключения. В основном речь идет о тестировании.

...