This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 2561. [fund.ts.v2] Incorrect exception specifications for 'swap' in C++ Extensions for Library Fundamentals

Section: 5.3.4 [fund.ts.v2::optional.object.swap], 3.7.8 [fund.ts.v2::propagate_const.modifiers] Status: Resolved Submitter: Daniel Krügler Opened: 2015-11-14 Last modified: 2022-07-28

Priority: 3

View all issues with Resolved status.

Discussion:

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` (5.3.4 [fund.ts.v2::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` (3.7.8 [fund.ts.v2::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_))`.

[2016-02-20, Ville comments]

Feedback from an implementation:

libstdc++ already applies the proposed resolution for `propagate_const`, but not for `optional`.

[2016-02-20, Daniel comments]

A recent paper update has been provided: P0185R0.

[2016-03, Jacksonville]

Add a link to 2456

[2016-11-08, Issaquah]

Not adopted during NB comment resolution

[2020-03-30; Daniel comments]

This has strong overlap with LWG 3413, which describes a sub-set of the problem here. Rebasing of the library fundamentals on C++20 has removed the mentioned problem for `optional`s free `swap`, so there are now no longer any further free `swap` function templates with conditionally `noexcept` specifications except for `propagate_const` (but now handled by LWG 3413).

[2022-07-28 Resolved by P0966R1 and LWG 3413. Status changed: New → Resolved.]

Proposed resolution: