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

### 2191. Incorrect specification of `match_results(match_results&&)`

Section: 30.9.2 [re.results.const] Status: WP Submitter: Pete Becker Opened: 2012-10-02 Last modified: 2021-10-14

Priority: 4

View all other issues in [re.results.const].

View all issues with WP status.

Discussion:

30.9.2 [re.results.const]/3: "Move-constructs an object of class `match_results` satisfying the same postconditions as Table 141."

Table 141 lists various member functions and says that their results should be the results of the corresponding member function calls on `m`. But `m` has been moved from, so the actual requirement ought to be based on the value that `m` had before the move construction, not on `m` itself.

In addition to that, the requirements for the copy constructor should refer to Table 141.

Ganesh:

Also, the requirements for move-assignment should refer to Table 141. Further it seems as if in Table 141 all phrases of "for all integers `n < m.size()`" should be replaced by "for all unsigned integers `n < m.size()`".

[2019-03-26; Daniel comments and provides wording]

The previous Table 141 (Now Table 128 in N4810) has been modified to cover now the effects of move/copy constructors and move/copy assignment operators. Newly added wording now clarifies that for move operations the corresponding values refer to the values of the move source before the operation has started.

Re Ganesh's proposal: Note that no further wording is needed for the move-assignment operator, because in the current working draft the move-assignment operator's Effects: element refers already to Table 128. The suggested clarification of unsigned integers has been implemented by referring to non-negative integers instead.

Upon suggestion from Casey, the wording also introduces Ensures: elements that refer to Table 128 and as drive-by fix eliminates a "Throws: Nothing." element from a `noexcept` function. Previous resolution [SUPERSEDED]:

> This wording is relative to N4810.

> 1. Add a new paragraph at the beginning of 30.9.2 [re.results.const] as indicated:

>    > -?- Table 128 lists the postconditions of `match_results` copy/move constructors and copy/move assignment operators. For move operations, the results of the expressions depending on the parameter `m` denote the values they had before the respective function calls.

> 2. Modify 30.9.2 [re.results.const] as indicated:

>    >     match_results(const match_results& m);

>    > > -3- Effects: Constructs an object of class `match_results`, as a copy of `m`.

>    > > -?- Ensures: As indicated in Table 128.

>    >     match_results(match_results&& m) noexcept;

>    > > -4- Effects: Move constructs an object of class `match_results` from `m` satisfying the same postconditions as Table 128. Additionally, the stored `Allocator` value is move constructed from `m.get_allocator()`.

>    > > -?- Ensures: As indicated in Table 128.

>    > > -5- Throws: Nothing.

>    >     match_results& operator=(const match_results& m);

>    > > -6- Effects: Assigns `m` to `*this`. The postconditions of this function are indicated in Table 128.

>    > > -?- Ensures: As indicated in Table 128.

>    >     match_results& operator=(match_results&& m);

>    > > -7- Effects: Move- assigns `m` to `*this`. The postconditions of this function are indicated in Table 128.

>    > > -?- Ensures: As indicated in Table 128.

> 3. Modify 30.9.2 [re.results.const], Table 128 — "`match_results` assignment operator effects", as indicated:

>    > Table 128 — `match_results` assignment operator effects copy/move operation postconditions
>    > Element | Value
>    > --- | ---
>    > `ready()` | `m.ready()`
>    > `size()` | `m.size()`
>    > `str(n)` | `m.str(n)` for all non-negative integers `n < m.size()`
>    > `prefix()` | `m.prefix()`
>    > `suffix()` | `m.suffix()`
>    > `(*this)[n]` | `m[n]` for all non-negative integers `n < m.size()`
>    > `length(n)` | `m.length(n)` for all non-negative integers `n < m.size()`
>    > `position(n)` | `m.position(n)` for all non-negative integers `n < m.size()`

[2021-06-25; Daniel comments and provides new wording]

The revised wording has been rebased to N4892. It replaces the now obsolete Ensures: element by the Postconditions: element and also restores the copy constructor prototype that has been eliminated by P1722R2 as anchor point for the link to Table 140.

[2021-06-30; Reflector poll]

Set status to Tentatively Ready after six votes in favour during reflector poll.

[2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4892.

1. Add a new paragraph at the beginning of 30.9.2 [re.results.const] as indicated:

   > -?- Table 140 [tab:re.results.const] lists the postconditions of `match_results` copy/move constructors and copy/move assignment operators. For move operations, the results of the expressions depending on the parameter `m` denote the values they had before the respective function calls.

2. Modify 30.9.2 [re.results.const] as indicated:

   >     explicit match_results(const Allocator& a);

   > > -1- Postconditions: `ready()` returns `false`. `size()` returns `0`.

   >     match_results(const match_results& m);

   > > -?- Postconditions: As specified in Table 140.

   >     match_results(match_results&& m) noexcept;

   > > -2- Effects: The stored `Allocator` value is move constructed from `m.get_allocator()`.

   > > -3- Postconditions: As specified in Table 140.

   >     match_results& operator=(const match_results& m);

   > > -4- Postconditions: As specified in Table 140.

   >     match_results& operator=(match_results&& m);

   > > -5- Postconditions: As specified in Table 140.

3. Modify 30.9.2 [re.results.const], Table 140 — "`match_results` assignment operator effects", [tab:re.results.const], as indicated:

   > Table 140 — `match_results` assignment operator effects copy/move operation postconditions
   > Element | Value
   > --- | ---
   > `ready()` | `m.ready()`
   > `size()` | `m.size()`
   > `str(n)` | `m.str(n)` for all non-negative integers `n < m.size()`
   > `prefix()` | `m.prefix()`
   > `suffix()` | `m.suffix()`
   > `(*this)[n]` | `m[n]` for all non-negative integers `n < m.size()`
   > `length(n)` | `m.length(n)` for all non-negative integers `n < m.size()`
   > `position(n)` | `m.position(n)` for all non-negative integers `n < m.size()`