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

`const`

and non-`const`

variables**Section:** 24.2.2 [container.requirements.general] **Status:** C++23
**Submitter:** Jonathan Wakely **Opened:** 2017-10-17 **Last modified:** 2023-11-22

**Priority: **3

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

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

**View all issues with** C++23 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.

Change 24.2.2 [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 denote~~s a~~non-`const`

values of type`X`

, and`rv`

denotes a non-`const`

rvalue of type`X`

.Change 24.2.2 [container.requirements.general], Table 83 "Container requirements", as indicated:

Table 83 — Container requirements Expression Return type Operational

semanticsAssertion/note

pre/post-conditionComplexity `[…]`

~~a~~r = rv`X&`

All existing elements

of`are either move`

~~a~~r

assigned to or

destroyed`shall be equal to`

~~a~~r

the value that`rv`

had

before this

assignmentlinear `[…]`

~~a~~r.swap(~~b~~s)`void`

exchanges the

contents of`and`

~~a~~r

~~b~~s(Note A) `[…]`

`swap(`

~~a~~r,~~b~~s)`void`

~~a~~r.swap(~~b~~s)(Note A)

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

**Previous resolution [SUPERSEDED]:**

This wording is relative to N4861.

Change 24.2.2 [container.requirements.general] as indicated:

[

Drafting note:

The following presentation also transforms the current list into a bullet list as we already have in 24.2.8 [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:

(4.1) —

`X`

denotes a container class containing objects of type`T`

,(4.2) —

`a`

~~and~~denotes a value`b`

~~s~~of type`X`

,(4.2) —

`b`

and`c`

denote (possibly`const`

) values of type`X`

,(4.3) —

`i`

and`j`

denote values of type (possibly`const`

)`X::iterator`

,(4.4) —

`u`

denotes an identifier,(?.?) —

`v`

denotes an lvalue of type (possibly`const`

)`X`

or an rvalue of type`const X`

,(4.5) —

`r`

`s`

and`t`

denote~~s a~~non-`const`

~~value~~lvalues of type`X`

, and(4.6) —

`rv`

denotes a non-`const`

rvalue of type`X`

.Change 24.2.2 [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

semanticsAssertion/note

pre/post-conditionComplexity `[…]`

`X(`

~~a~~v)Preconditions:`T`

isCpp17CopyInsertable

into`X`

(see below).

Postconditions:`.`

~~a~~v == X(~~a~~v)linear `X u(`

~~a~~v);

X u =~~a~~v;Preconditions:`T`

isCpp17CopyInsertable

into`X`

(see below).

Postconditions:`u ==`

.~~a~~vlinear `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

~~a~~t = rv`X&`

All existing elements

of`are either move`

~~a~~t

assigned to or

destroyed`shall be equal to`

~~a~~t

the value that`rv`

had

before this

assignmentlinear `[…]`

~~a~~c == bconvertible to `bool`

`==`

is an equivalence relation.

`equal(`

~~a~~c.begin(),

~~a~~c.end(),

b.begin(),

b.end())Preconditions:`T`

meets the

Cpp17EqualityComparablerequirementsConstant if `,`

~~a~~c.size() != b.size()

linear otherwise

~~a~~c != bconvertible to `bool`

Equivalent to `!(`

~~a~~c == b)linear

~~a~~t.swap(~~b~~s)`void`

exchanges the

contents of`and`

~~a~~t

~~b~~s(Note A) `swap(`

~~a~~t,~~b~~s)`void`

~~a~~t.swap(~~b~~s)(Note A) `r = a`

`X&`

Postconditions:`r == a`

.~~linear~~

~~a~~c.size()`size_type`

`distance(`

~~a~~c.begin(),~~a~~c.end())constant

~~a~~c.max_size()`size_type`

`distance(begin(), end())`

for the largest

possible containerconstant

~~a~~c.empty()convertible to `bool`

~~a~~c.begin() ==~~a~~c.end()constant

*[2022-04-20; Jonathan rebases the wording on the latest draft]*

*[2022-09-05; Reflector poll]*

Set status to Tentatively Ready after five votes in favour during reflector poll in April 2022.

*[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP.]*

**Proposed resolution:**

This wording is relative to N4910.

Change 24.2.2 [container.requirements.general] as indicated:

[

*Drafting note:*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`

-1- In subclause [container.gen.reqmts],

(1.1) —

`X`

denotes a container class containing objects of type`T`

,(1.2) —

`a`

~~and~~denotes a value of type`b`

denote values`X`

,(?.?) —

`b`

and`c`

denote values of type (possibly`const`

)`X`

,(1.3) —

`i`

and`j`

denote values of type (possibly`const`

)`X::iterator`

,(1.4) —

`u`

denotes an identifier,(?.?) —

`v`

denotes an lvalue of type (possibly`const`

)`X`

or an rvalue of type`const X`

,(1.5) —

`r`

denotes a`s`

and`t`

denote non-`const`

~~value~~lvalues of type`X`

, and(1.6) —

`rv`

denotes a non-`const`

rvalue of type`X`

.

Change 24.2.2.2 [container.reqmts] as indicated:

[

*Drafting note:*The following presentation also moves the copy-assignment expression just before the move-assignment expression]X u(

~~a~~v); X u =~~a~~v;-12-

*Preconditions:*`T`

is*Cpp17CopyInsertable*into`X`

(see below).-13-

*Postconditions:*`u ==`

.~~a~~v-14-

*Complexity:*Linear.X u(rv); X u = rv;

-15-

*Postconditions:*`u`

is equal to the value that`rv`

had before this construction.-14-

*Complexity:*Linear for`array`

and constant for all other standard containers.t = v

-?-

*Result:*`X&`

.-?-

*Postconditions:*`t == v`

.-?-

*Complexity:*Linear.~~a~~t = rv-17-

*Result:*`X&`

.-18-

*Effects:*All existing elements of

are either move assigned to or destroyed.~~a~~t-19-

*Postconditions:*

shall be equal to the value that~~a~~t`rv`

had before this assignment.-20-

*Complexity:*Linear.[…]

~~a~~b.begin()-24-

*Result:*`iterator`

;`const_iterator`

for constant~~a~~b.-25-

*Returns:*An iterator referring to the first element in the container.-26-

*Complexity:*Constant.~~a~~b.end()-27-

*Result:*`iterator`

;`const_iterator`

for constant~~a~~b.-28-

*Returns:*An iterator which is the past-the-end value for the container.-29-

*Complexity:*Constant.~~a~~b.cbegin()-30-

*Result:*`const_iterator`

.-31-

*Returns:*`const_cast<X const&>(`

~~a~~b).begin()-32-

*Complexity:*Constant.~~a~~b.cend()-33-

*Result:*`const_iterator`

.-34-

*Returns:*`const_cast<X const&>(`

~~a~~b).end()-35-

*Complexity:*Constant.[…]

~~a~~c == b-39-

*Preconditions:*`T`

meets the*Cpp17EqualityComparable*requirements.-40-

*Result:*Convertible to`bool`

.-41-

*Returns:*`equal(`

.~~a~~c.begin(),~~a~~c.end(), b.begin(), b.end())[

*Note 1:*The algorithm`equal`

is defined in 27.6.13 [alg.equal].*— end note*]-42-

*Complexity:*Constant if

, linear otherwise.~~a~~c.size() != b.size()-43-

*Remarks:*`==`

is an equivalence relation.~~a~~c != b-44-

*Effects:*Equivalent to`!(`

.~~a~~c == b)~~a~~t.swap(~~b~~s)-45-

*Result:*`void`

.-46-

*Effects:*Exchanges the contents of

and~~a~~t

.~~b~~s-47-

*Complexity:*Linear for`array`

and constant for all other standard containers.swap(

~~a~~t,~~b~~s)-48-

*Effects:*Equivalent to~~a~~t.swap(~~b~~s)~~r = a~~~~-49-~~*Result:*`X&`

.~~-50-~~*Postconditions:*`r == a`

.~~-51-~~*Complexity:*Linear.~~a~~c.size()-52-

*Result:*`size_type`

.-53-

*Returns:*`distance(`

, i.e. the number of elements in the container.~~a~~c.begin(),~~a~~c.end())-54-

*Complexity:*Constant.-55-

*Remarks:*The number of elements is defined by the rules of constructors, inserts, and erases.~~a~~c.max_size()-56-

*Result:*`size_type`

.-57-

*Returns:*`distance(begin(), end())`

for the largest possible container.-58-

*Complexity:*Constant.~~a~~c.empty()-59-

*Result:*Convertible to`bool`

.-60-

*Returns:*~~a~~c.begin() ==~~a~~c.end())-61-

*Complexity:*Constant.-62-

*Remarks:*If the container is empty, then

is~~a~~c.empty()`true`

.