@DeadMG's answer led me to Conservative use of noexcept in the Library, which says the following:
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.
where narrow and wide contracts are defined as:
A wide contract for a function or operation does not specify any undefined behavior. Such a contract has no preconditions: A function
with a wide contract places no additional runtime constraints on its
arguments, on any object state, nor on any external global state.
A narrow contract is a contract which is not wide. Narrow contracts for a functions or operations result in undefined behavior when called
in a manner that violates the documented contract. Such a contract
specifies at least one precondition involving its arguments, object
state, or some external global state, such as the initialization of a
static object.
At the end of that document, operators functors previously marked noexcept
are no longer noexcept
.
So if I understand this correctly, the new operators functors in <functional>
have wide-contracts, but might throw sometimes depending on the types they act on. As such, they are not unconditionally noexcept(true)
. Due to this, it is left to the library implementors to decide:
their use be left as a library vendor quality-of-implementation
feature until we have more experience.