Что-нибудь мешает std :: optional :: value_or () быть условно noexcept?

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

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

Effects: Equivalent to:

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

Remarks: If is_copy_constructible_v<T> && is_convertible_v<U&&, T> is false, the program is ill-formed.

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

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

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

Так нельзя ли объявить value_ornoexcept при is_nothrow_copy_constructible<T> && noexcept(static_cast<T>(std::forward<U>(v)))?

Условное noexcept не очень часто используется в стандарте C++, может «считаться» чем-то, что препятствует его использованию здесь.

Yakk - Adam Nevraumont 03.05.2018 20:59

@Yakk Я бы подумал, что это отвечает на поставленный вопрос, но сразу же возникает другой: почему он не используется широко?

lisyarus 03.05.2018 21:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
2
399
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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


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

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

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

Adopted Guidelines

  • No library destructor should throw. They shall use the implicitly supplied (non-throwing) exception specification.
  • Each library function having a wide contract, that the LWG agree cannot throw, should be marked as unconditionally noexcept.
  • If a library swap function, move-constructor, or move-assignment operator is conditionally-wide (i.e. can be proven to not throw by applying the noexcept operator) then it should be marked as conditionally noexcept. No other function should use a conditional noexcept specification.
  • Library functions designed for compatibility with “C” code (such as the atomics facility), may be marked as unconditionally noexcept.

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

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

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

Соответствующее руководство по этому вопросу находится на странице 2: только swap() и назначения конструкторов перемещения в библиотеке условно noexcept.

Barry 03.05.2018 22:02

На предыдущем заседании комитета, я думаю, они согласились сделать «типы обертки» условно noexcept на основе операций типов, которые они оборачивают. std::optional и std::variant будут такими типами оболочки.

Morwenn 03.05.2018 22:40

Это хороший ответ на любой вопрос "Почему X не noexcept".

kmdreko 03.05.2018 23:00

@morwenn у вас есть документация или ссылки на этот счет, чтобы я мог вставить цитату с указанием авторства?

Yakk - Adam Nevraumont 04.05.2018 03:18

@Morwenn, что вы имеете в виду, делая тип условным noexcept? Вы имеете в виду какие-то конкретные операции с ними в частности? В C++ 17 optional(optional&& rhs) уже является noexcept, если is_nothrow_move_constructible_v<T> (и аналогично для назначения перемещения). variant делает то же самое, но он должен действовать для всех типов в оболочке.

knatten 04.05.2018 09:31

@Yakk Документ, о котором я упоминал, был [P0884 - Расширение политики noexcept] (wg21.link/P0884], что на самом деле довольно кратко. В документе цитируются std::atomic и предлагаемый std::function_ref в качестве примеров типов упаковки. Я только что проверил протокол собрания (не для всех) и был поднят вопрос о std::optional и std::variant, но фактический ответ состоял в том, что цель статьи заключалась в том, чтобы расширить условную политику noexcept, чтобы не принимать твердых решений, поэтому нет однозначного ответа для этих типов. Очевидно, комитет был решительно за принятие этой статьи.

Morwenn 04.05.2018 09:37

@knatten Просто еще раз перепроверил документ, и на самом деле он предлагает только условный noexcept для конструктора по умолчанию, конструктора копирования и оператора присваивания копии для типов оболочки, поэтому в отличие от того, что я думал, это никак не повлияет на value_or, извините: /

Morwenn 04.05.2018 09:39

Другие вопросы по теме