Date
2015-12-11.00:00:00
Message id
7641

Content

Addresses: fund.ts.v2

As pointed out in N4511, the Library fundamentals are affected by a similar problem as described in LWG 2456. First, it is caused by optional's member swap ([optional.object.swap]):

void swap(optional<T>& rhs) noexcept(see below);

with

The expression inside noexcept is equivalent to:

is_nothrow_move_constructible_v<T> && noexcept(swap(declval<T&>(), declval<T&>()))

Again, the unqualified lookup for swap finds the member swap instead of the result of a normal argument-depending lookup, making this ill-formed.

A second example of such a problem recently entered the arena with the addition of the propagate_const template with another member swap ([propagate_const.modifiers]):

constexpr void swap(propagate_const& pt) noexcept(see below);

-2- The constant-expression in the exception-specification is noexcept(swap(t_, pt.t_)).

A working approach is presented in N4511. By adding a new trait to the standard library and referencing this by the library fundamentals (A similar approach had been applied in the file system specification where the quoted manipulator from C++14 had been referred to, albeit the file system specification is generally based on the C++11 standard), optional's member swap exception specification could be rephrased as follows:

The expression inside noexcept is equivalent to:

is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>noexcept(swap(declval<T&>(), declval<T&>()))

and propagate_const's member swap exception specification could be rephrased as follows:

constexpr void swap(propagate_const& pt) noexcept(see below);

-2- The constant-expression in the exception-specification is is_nothrow_swappable_v<T>noexcept(swap(t_, pt.t_)).