В N3421 — Расширение функторов операторов<>, новая специализация для объектов функции std:
template <> struct plus<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) + std::forward<U>(u));
};
вместо
template <> struct plus<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
noexcept(noexcept(decltype(std::forward<T>(t) + std::forward<U>(u))
(std::move(std::forward<T>(t) + std::forward<U>(u)))))
-> decltype(std::forward<T>(t) + std::forward<U>(u));
};
noexcept
дело в этом случае использования?Редактировать: ссылка на рабочий черновик в github.
Изменить 2: ссылка на libc ++ плюс специализация.
Существующие рекомендации LWG не поощряют использование noexcept. Они не принимают никаких исключений, кроме функций с широкими контрактами, только функции с узкими контрактами. Я не помню точно, как эти термины были определены, но я могу сказать вам, что я присутствовал на встрече в Бристоле, обсуждая noexcept
и они отказались поставить его на функцию, потому что это был широкий контракт, который я считал глупым безумием.
Так что, вероятно, это не здесь по одной из двух причин. Во-первых, Комитет и авторы документов еще не привыкли рассматривать noexcept
в каждом случае — похоже на constexpr
, В этом случае автор статьи (STL), вероятно, просто забыл добавить его.
Во-вторых, у LWG есть некоторые безумные чрезмерные ограничения на то, когда они примут noexcept
,
Ответ @ DeadMG привел меня к Консервативное использование noexcept в библиотеке, что говорит следующее:
Принятые руководящие принципы
Никакой деструктор библиотеки не должен выбрасывать. Они должны использовать неявно предоставленную (не генерирующую) спецификацию исключений.
Каждая библиотечная функция, имеющая широкий контракт, который LWG не может выполнить, должна быть помечена как безусловно noexcept.
Если функция обмена библиотекой, оператор-конструктор перемещения или оператор присваивания перемещения является условно-широким (т. Е. Может быть доказано, что
применяя оператор noexcept), то он должен быть помечен как
условно нет, кроме Никакая другая функция не должна использовать условную
нет, кроме спецификации.Библиотечные функции, разработанные для совместимости с кодом «С» (например, средство атомарного анализа), могут быть помечены как безусловно без исключения.
где узкие и широкие контракты определяются как:
Широкий контракт для функции или операции не определяет какого-либо неопределенного поведения. Такой договор не имеет предварительных условий: функция
с широким контрактом не накладывает никаких дополнительных ограничений на время его выполнения
аргументы, ни о каком состоянии объекта, ни о каком-либо внешнем глобальном состоянии.Узкий контракт — это контракт, который не является широким. Узкие контракты для функций или операций приводят к неопределенному поведению при вызове
таким образом, что нарушает документально подтвержденный договор. Такой контракт
указывает хотя бы одно предварительное условие, включающее его аргументы, объект
состояние, или некоторое внешнее глобальное состояние, такое как инициализация
статический объект
В конце этого документа операторы-функторы ранее отмечены noexcept
больше не noexcept
,
Так что, если я правильно понимаю, новые операторы функторы в <functional>
имеют широкие контракты, но иногда могут выбрасывать в зависимости от типов, на которые они действуют. Как таковые, они не безоговорочно noexcept(true)
, В связи с этим разработчикам библиотеки остается решать:
их использование должно быть оставлено в качестве поставщика реализации библиотеки качества
пока у нас больше опыта.