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

**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

Xdenotes a container class containing objects of typeT,aandbdenote values of typeX,udenotes an identifier,rdenotes a non-constvalue of typeX, andrvdenotes a non-constrvalue of typeX.

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

Xdenotes a container class containing objects of typeT,aandbdenote values of typeX,udenotes an identifier,rand s denote~~s a~~non-constvalues of typeX, andrvdenotes a non-constrvalue of typeX.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 = rvX&All existing elements

ofare either move~~a~~r

assigned to or

destroyedshall be equal to~~a~~r

the value thatrvhad

before this

assignmentlinear […]~~a~~r.swap(~~b~~s)voidexchanges the

contents ofand~~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

rbys, because it is easy to confuse withrvbut means an lvalue instead, and the other container tables use it rarely and for something completely different (iterator value)A separate symbol

vis introduced to unambigiously distinguish the counterpart of a non-constrvalue (See 16.4.4.2 [utility.arg.requirements])Two separate symbols

bandcrepresent now "(possiblyconst) values, while the existing symbolarepresents an unspecified value, whose meaning becomes defined when context is provided, e.g. for overloads likebegin()andend-4- In Tables 73, 74, and 75:

(4.1) —

Xdenotes a container class containing objects of typeT,(4.2) —

a~~and~~denotes a valueb~~s~~of typeX,(4.2) —

bandcdenote (possiblyconst) values of typeX,(4.3) —

iandjdenote values of type (possiblyconst)X::iterator,(4.4) —

udenotes an identifier,(?.?) —

vdenotes an lvalue of type (possiblyconst)Xor an rvalue of typeconst X,(4.5) —

rsandtdenote~~s a~~non-const~~value~~lvalues of typeX, and(4.6) —

rvdenotes a non-constrvalue of typeX.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:TisCpp17CopyInsertable

intoX(see below).

Postconditions:.~~a~~v == X(~~a~~v)linear X u(~~a~~v);

X u =~~a~~v;Preconditions:TisCpp17CopyInsertable

intoX(see below).

Postconditions:u ==.~~a~~vlinear X u(rv);

X u = rv;Postconditions:uis equal to the value

thatrvhad before this construction(Note B) t = vX&Postconditions:t == v.linear ~~a~~t = rvX&All existing elements

ofare either move~~a~~t

assigned to or

destroyedshall be equal to~~a~~t

the value thatrvhad

before this

assignmentlinear […]~~a~~c == bconvertible to bool==is an equivalence relation.

equal(~~a~~c.begin(),

~~a~~c.end(),

b.begin(),

b.end())Preconditions:Tmeets the

Cpp17EqualityComparablerequirementsConstant if ,~~a~~c.size() != b.size()

linear otherwise~~a~~c != bconvertible to boolEquivalent to !(~~a~~c == b)linear ~~a~~t.swap(~~b~~s)voidexchanges the

contents ofand~~a~~t~~b~~s(Note A) swap(~~a~~t,~~b~~s)void~~a~~t.swap(~~b~~s)(Note A) r = aX&Postconditions:r == a.~~linear~~~~a~~c.size()size_typedistance(~~a~~c.begin(),~~a~~c.end())constant ~~a~~c.max_size()size_typedistance(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 ofare 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 ofand~~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, thenis~~a~~c.empty()`true`.