C++ named requirements: SequenceContainer
A SequenceContainer is a Container that stores objects of the same type in a linear arrangement.
Requirements
Legend |
|
X
|
A sequence container class |
T
|
The element type of
X
|
a |
A value of type
X
|
u | The name of a declared variable |
A
|
The allocator type of
X
:
|
i , j |
LegacyInputIterator
s
such that
[
i
,
j
)
is a
valid range
and that the iterators refer to elements implicitly convertible to
value_type
|
rg (since C++23) |
A value of a type
R
that models
container-compatible-range
<T>
|
il (since C++11) | An object of type std:: initializer_list < value_type > |
n |
A value of type
X::size_type
|
p | A valid const iterator into a |
q | A valid dereferenceable const iterator into a |
q1 , q2 |
Two const iterators into
a
such that
[
q1
,
q2
)
is a valid range
|
t |
An
lvalue
or const rvalue
(since C++11)
of type
X::value_type
|
rv (since C++11) |
A non-const rvalue of type
X::value_type
|
Args
(since C++11)
|
A template parameter pack |
args (since C++11) |
A function parameter pack with the pattern
Arg&&
|
The type
X
satisfies
SequenceContainer
if
-
The type
X
satisfies Container , and - The following statements and expressions must be valid and have their specified effects for all sequence containers except std::array (see notes ) (since C++11) :
Statement | Effects | Conditions [1] | ||
---|---|---|---|---|
X u ( n, t ) | Constructs the sequence container holding n copies of t | Pre |
T
is
CopyInsertable
into
X
|
|
Post |
std::
distance
(
u.
begin
(
)
, u.
end
(
)
)
== n |
|||
X u ( i, j ) |
Constructs the sequence container equal, element-wise, to the range
[
i
,
j
)
|
Pre |
T
is
EmplaceConstructible
from
*
i
into
X
|
|
Post |
std::
distance
(
u.
begin
(
)
, u.
end
(
)
)
== std:: distance ( i, j ) |
|||
Expression | Type | Effects | Conditions | |
X
(
std::
from_range
, rg
)
(since C++23) |
X
|
Constructs the sequence container equal, element-wise, to the range rg | Pre |
T
is
EmplaceConstructible
into
X
from
*
ranges::
begin
(
rg
)
|
Post |
|
|||
X
(
il
)
(since C++11) |
X
|
Equivalent to
X
(
il.
begin
(
)
,
il. end ( ) ) |
No explicit requirement | |
a
=
il
(since C++11) |
X&
|
Assigns the range represented by il into a . [2] | Pre |
T
is
CopyInsertable
and
CopyAssignable
|
Post | Existing elements of a are destroyed or assigned to | |||
a.
emplace
(
p, args
)
(since C++11) |
iterator
|
Insert an object of type
T
, constructed with
std::
forward
<
Args
>
(
args
)
before
p
|
Pre |
T
is
EmplaceConstructible
|
Post | The returned iterator points at the element constructed from args into a | |||
a. insert ( p, t ) |
iterator
|
Inserts a copy of t before p | Pre |
T
is
CopyInsertable
|
Post | The returned iterator points at the copy of t inserted into a | |||
a.
insert
(
p, rv
)
(since C++11) |
iterator
|
Inserts a copy of rv before p , possibly using move semantics | Pre |
T
is
MoveInsertable
|
Post | The returned iterator points at the copy of rv inserted into a | |||
a. insert ( p, n, t ) |
iterator
|
Inserts n copies of t before p | Pre |
T
is
CopyInsertable
and
CopyAssignable
|
Post | The returned iterator points at the copy of the first element inserted into a or is p for n == 0 | |||
a. insert ( p, i, j ) |
iterator
|
Inserts copies of elements in
[
i
,
j
)
before
p
|
Pre |
T
is
EmplaceConstructible
and
i
and
j
are not in
a
|
Post |
|
|||
a.
insert_range
(
p, rg
)
(since C++23) |
iterator
|
Inserts copies of elements in rg before p | Pre |
|
Post |
|
|||
a.
insert
(
p, il
)
(since C++11) |
iterator
|
Equivalent to
a.
insert
(
p,
il. begin ( ) , il. end ( ) ) |
Pre | No explicit requirement |
Post | The returned iterator points at the copy of the first element inserted into a or is p if il is empty | |||
a. erase ( q ) |
iterator
|
Erases the element pointed to by q | Pre | No explicit requirement |
Post | The returned iterator points at the element that was immediately following q prior to erasure, or a. end ( ) if no such element exists | |||
a. erase ( q1, q2 ) |
iterator
|
Erases elements in
[
q1
,
q2
)
|
Pre | No explicit requirement |
Post | The returned iterator points at the element that was pointed by q2 prior to any erasure, or a. end ( ) if no such element exists | |||
a. clear ( ) | void | Destroys all elements in a | Pre | No explicit requirement |
Post |
|
|||
a. assign ( i, j ) | void |
Replaces elements in
a
with a copy of
[
i
,
j
)
|
Pre |
|
Post |
Each iterator in
[
i
,
j
)
is dereferenced once.
|
|||
a.
assign_range
(
rg
)
(since C++23) |
void | Replaces elements in a with a copy of each element in rg | Pre |
|
Post |
|
|||
a.
assign
(
il
)
(since C++11) |
void |
Equivalent to
a.
assign
(
il.
begin
(
)
,
|
No explicit requirement | |
a. assign ( n, t ) | void | Replaces elements in a with n copies of t | Pre |
T
is
CopyInsertable
and
CopyAssignable
|
Post | No explicit requirement | |||
Notes | ||||
|
Optional operations
The following expressions must be valid and have their specified effects for the sequence containers named, all operations
except
prepend_range
and
append_range
(since C++23)
take amortized constant time:
Expression | Type | Effects | Preconditions [1] | Containers |
---|---|---|---|---|
a. front ( ) |
reference
, or
|
Returns * a. begin ( ) | No explicit requirement | std::basic_string , std::array , std::deque , std::forward_list , std::inplace_vector , std::list , std::vector |
a. back ( ) |
reference
, or
|
Equivalent to
auto
tmp
=
a.
end
(
)
;
-- tmp ; return * tmp ; |
No explicit requirement | std::basic_string , std::array , std::deque , std::inplace_vector , std::list , std::vector |
a.
emplace_front
(
args
)
(since C++11) |
void |
Prepends a
T
constructed with
std::
forward
<
Args
>
( args ) ... |
T
is
EmplaceConstructible
into
X
from
args
|
std::deque , std::forward_list , std::list |
a.
emplace_back
(
args
)
(since C++11) |
void |
Appends a
T
constructed with
std::
forward
<
Args
>
( args ) ... |
T
is
EmplaceConstructible
into
X
from
args
|
std::deque , std::inplace_vector , std::list , std::vector |
a. push_front ( t ) | void | Prepends a copy of t |
T
is
CopyInsertable
into
X
|
std::deque , std::forward_list , std::list |
a.
push_front
(
rv
)
(since C++11) |
void | Prepends a copy of rv , possibly using move semantics |
T
is
MoveInsertable
into
X
|
|
a.
prepend_range
(
rg
)
(since C++23) |
void | Inserts [2] copies of elements in rg before begin ( ) , each iterator in rg is dereferenced once |
T
is
EmplaceConstructible
into
X
from
*
ranges::
begin
(
rg
)
|
std::deque , std::forward_list , std::list |
a. push_back ( t ) | void | Appends a copy of t |
T
is
CopyInsertable
into
X
|
std::basic_string , std::deque , std::inplace_vector , std::list , std::vector |
a.
push_back
(
rv
)
(since C++11) |
void | Appends a copy of rv , possibly using move semantics |
T
is
MoveInsertable
into
X
|
|
a.
append_range
(
rg
)
(since C++23) |
void | Inserts [2] copies of elements in rg before end ( ) dereferencing each iterator in rg once |
T
is
EmplaceConstructible
into
X
from
*
ranges::
begin
(
rg
)
|
std::deque , std::inplace_vector , std::list , std::vector |
a. pop_front ( ) | void | Destroys the first element | a. empty ( ) is false | std::deque , std::forward_list , std::list |
a. pop_back ( ) | void | Destroys the last element | a. empty ( ) is false | std::basic_string , std::deque , std::inplace_vector , std::list , std::vector |
a [ n ] |
reference
, or
|
Returns * ( a. begin ( ) + n ) | No explicit requirement | std::basic_string , std::array , std::deque , std::inplace_vector , std::vector |
a. at ( n ) |
reference
, or
|
Returns * ( a. begin ( ) + n ) , throws std::out_of_range if n >= size ( ) | No explicit requirement | |
Notes | ||||
Additionally, for every sequence container:
-
A constructor template that takes two input iterators and the member function template overloads of
insert
,append
,assign
,replace
that take two input iterators do not participate in overload resolution if the corresponding template argument does not satisfy LegacyInputIterator .
|
(since C++17) |
Standard library
The following standard library string types and containers satisfy the SequenceContainer requirements:
stores and manipulates sequences of characters
(class template) |
|
(C++11)
|
fixed-sized inplace contiguous array
(class template) |
dynamic contiguous array
(class template) |
|
(C++26)
|
dynamically-resizable, fixed capacity, inplace contiguous array
(class template) |
double-ended queue
(class template) |
|
(C++11)
|
singly-linked list
(class template) |
doubly-linked list
(class template) |
Usage notes
Container | Pros | Cons |
---|---|---|
std::vector | Fast access | Mostly inefficient insertions/deletions |
std:: inplace_vector | Fast access, inplace contiguous storage | Fixed capacity and mostly inefficient insertions/deletions |
std::array | Fast access, inplace contiguous storage | Fixed number of elements and no insertion/deletion |
std::deque | Fast access, efficient insertion/deletion at the beginning/end | Inefficient insertion/deletion in the middle of the sequence |
std::list
std::forward_list |
Efficient insertion/deletion in the middle of the sequence | Access is mostly linear-time |
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 139 | C++98 |
the optional operations were not required to
be implemented for the designated containers |
required with
amortized time |
LWG 149 | C++98 |
a.
insert
(
p, t
)
returned
iterator
while
a. insert ( p, n, t ) and a. insert ( p, n, t ) returned void |
they all return
iterator
|
LWG 151 | C++98 | q1 was required to be dereferenceable [1] | it can be non-dereferenceable |
LWG 355 | C++98 |
calling
a.
back
(
)
or
a.
pop_back
(
)
would
execute -- a. end ( ) , which is dangerous [2] |
decrements a copy
of a. end ( ) instead |
LWG 589 | C++98 |
the elements that
i
and
j
refer to
might not be convertible to
value_type
|
they are implicitly
convertible to
value_type
|
LWG 2194 | C++11 |
std::queue
,
std::priority_queue
and
std::stack were also SequenceContainer s [3] |
they are not SequenceContainer s |
LWG 3927 | C++98 | operator [ ] had no implicit requirement | added the implicit requirement |
- ↑ It is a defect because it makes the behavior of a. erase ( a. begin ( ) , a. end ( ) ) undefined is a is an empty container.
- ↑ If the type of a. end ( ) is a fundamental type, -- a. end ( ) is ill-formed. It is dangerous when the type of a is templated, in this case this bug can be difficult to be found.
- ↑ They were not documented as SequenceContainer s in C++98.