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

### 3028. Container requirements tables should distinguish `const` and non-`const` variables

Section: 22.2.1 [container.requirements.general] Status: New Submitter: Jonathan Wakely Opened: 2017-10-17 Last modified: 2020-09-06

Priority: 3

View other active issues in [container.requirements.general].

View all other issues in [container.requirements.general].

View all issues with New status.

Discussion:

[container.requirements.general] p4 says:

> In Tables 83, 84, and 85 `X` denotes a container class containing objects of type `T`, `a` and `b` denote values of type `X`, `u` denotes an identifier, `r` denotes a non-`const` value of type `X`, and `rv` denotes a non-`const` rvalue of type `X`.

This doesn't say anything about whether `a` and `b` are allowed to be `const`, or must be non-`const`. In fact Table 83 uses them inconsistently, e.g. the rows for "`a = rv`" and "`a.swap(b)`" most certainly require them to be non-`const`, but all other uses are valid for either `const` or non-`const X`.

[2017-11 Albuquerque Wednesday night issues processing]

Priority set to 3; Jonathan to provide updated wording.

Wording needs adjustment - could use "possibly const values of type X"

Will distinguish between lvalue/rvalue

Previous resolution [SUPERSEDED]:

> This wording is relative to N4687.

> 1. Change 22.2.1 [container.requirements.general] p4 as indicated:

>    > -4- In Tables 83, 84, and 85 `X` denotes a container class containing objects of type `T`, `a` and `b` denote values of type `X`, `u` denotes an identifier, `r` and s denotes a non-`const` values of type `X`, and `rv` denotes a non-`const` rvalue of type `X`.

> 2. Change 22.2.1 [container.requirements.general], Table 83 "Container requirements", as indicated:

>    > Table 83 — Container requirements
>    > Expression | Return type | Operational semantics | Assertion/note pre/post-condition | Complexity
>    > --- | --- | --- | --- | ---
>    > `[…]`
>    > `ar = rv` | `X&` | All existing elements of `ar` are either move assigned to or destroyed | `ar` shall be equal to the value that `rv` had before this assignment | linear
>    > `[…]`
>    > `ar.swap(bs)` | `void` |  | exchanges the contents of `ar` and `bs` | (Note A)
>    > `[…]`
>    > `swap(ar, bs)` | `void` | `ar.swap(bs)` |  | (Note A)

[2020-05-03; Daniel provides alternative wording]

Proposed resolution:

This wording is relative to N4861.

1. Change 22.2.1 [container.requirements.general] as indicated:

   > [Drafting note:

   > - The following presentation also transforms the current list into a bullet list as we already have in 22.2.7 [unord.req] p11

   > - It has been decided to replace the symbol `r` by `s`, because it is easy to confuse with `rv` but means an lvalue instead, and the other container tables use it rarely and for something completely different (iterator value)

   > - A separate symbol `v` is introduced to unambigiously distinguish the counterpart of a non-`const` rvalue (See 16.4.4.2 [utility.arg.requirements])

   > - Two separate symbols `b` and `c` represent now "(possibly `const`) values, while the existing symbol `a` represents an unspecified value, whose meaning becomes defined when context is provided, e.g. for overloads like `begin()` and `end`

   > -4- In Tables 73, 74, and 75:

   > 1. (4.1) — `X` denotes a container class containing objects of type `T`,

   > 2. (4.2) — `a` and `b` denotes a values of type `X`,

   > 3. (4.2) — `b` and `c` denote (possibly `const`) values of type `X`,

   > 4. (4.3) — `i` and `j` denote values of type (possibly `const`) `X::iterator`,

   > 5. (4.4) — `u` denotes an identifier,

   > 6. (?.?) — `v` denotes an lvalue of type (possibly `const`) `X` or an rvalue of type `const X`,

   > 7. (4.5) — `r` `s` and `t` denotes a non-`const` value lvalues of type `X`, and

   > 8. (4.6) — `rv` denotes a non-`const` rvalue of type `X`.

2. Change 22.2.1 [container.requirements.general], Table 73 "Container requirements" [tab:container.req], as indicated:

   > [Drafting note: The following presentation also moves the copy-assignment expression just before the move-assignment expression]

   > Table 73: — Container requirements [tab:container.req]
   > Expression | Return type | Operational semantics | Assertion/note pre/post-condition | Complexity
   > --- | --- | --- | --- | ---
   > `[…]`
   > `X(av)` |  |  | Preconditions: `T` is Cpp17CopyInsertable into `X` (see below). Postconditions: `av == X(av)`. | linear
   > `X u(av); X u = av;` |  |  | Preconditions: `T` is Cpp17CopyInsertable into `X` (see below). Postconditions: `u == av`. | linear
   > `X u(rv); X u = rv;` |  |  | Postconditions: `u` is equal to the value that `rv` had before this construction | (Note B)
   > `t = v` | `X&` |  | Postconditions: `t == v`. | linear
   > `at = rv` | `X&` | All existing elements of `at` are either move assigned to or destroyed | `at` shall be equal to the value that `rv` had before this assignment | linear
   > `[…]`
   > `ac == b` | convertible to `bool` | `==` is an equivalence relation. `equal(ac.begin(), ac.end(), b.begin(), b.end())` | Preconditions: `T` meets the Cpp17EqualityComparable requirements | Constant if `ac.size() != b.size()`, linear otherwise
   > `ac != b` | convertible to `bool` | Equivalent to `!(ac == b)` |  | linear
   > `at.swap(bs)` | `void` |  | exchanges the contents of `at` and `bs` | (Note A)
   > `swap(at, bs)` | `void` | `at.swap(bs)` |  | (Note A)
   > `r = a` | `X&` |  | Postconditions: `r == a`. | linear
   > `ac.size()` | `size_type` | `distance(ac.begin(), ac.end())` |  | constant
   > `ac.max_size()` | `size_type` | `distance(begin(), end())` for the largest possible container |  | constant
   > `ac.empty()` | convertible to `bool` | `ac.begin() == ac.end()` |  | constant