Requisitos denominados de C++: SequenceContainer
De cppreference.com
Un SequenceContainer es un contenedor (Container) que almacena objetos del mismo tipo en una disposición lineal.
Requisitos
Leyenda | |
X
|
Una clase de contenedor secuencial |
T
|
El tipo de elemento de X
|
a
|
Un valor de tipo X
|
u
|
El nombre de una variable declarada |
A
|
El tipo de asignador de X:
|
i, j
|
InputIterator tal que [i, j) sea un rango válido y que los iteradores hagan referencia a elementos convertibles implícitamente a tipos de valor
|
rg (desde C++23)
|
Un valor de tipo R que modela container-compatible-range<T>
|
il (desde C++11)
|
Un objeto de tipo std::initializer_list<value_type>
|
n
|
Un valor de tipo X::size_type
|
p
|
Un iterador constante válido en a
|
q
|
Un iterador constante desreferenciable válido en a
|
q1, q2
|
Dos iteradores constantes en a cuyo [q1, q2) es un rango válido
|
t
|
Un lvalor o rvalor constante (desde C++11) de tipo X::value_type
|
rv (desde C++11)
|
Un rvalor con constante de tipo X::value_type
|
Args (desde C++11)
|
Un paquete de parámetros de plantilla |
args (desde C++11)
|
Un paquete de parámetros de plantilla con el patrón Arg&&
|
El tipo X satisface SequenceContainer si
- El tipo
Xsatisface Container, y - Las siguientes sentencias y expresiones deben ser válidas y tener los efectos especificados para todos los contenedores secuenciales excepto std::array (véase notas) (desde C++11):
| Sentencia | Efectos | Condiciones[1] | ||
|---|---|---|---|---|
X u(n, t)
|
Construye un contenedor secuencial que contiene n copias de t.
|
Pre | T es CopyInsertable en X.
| |
| Pos | std::distance(u.begin(), u.end()) == n es true.
| |||
X u(i, j)
|
Construye el contenedor secuencial igual, elemento por elemento, al rango [i, j).
|
Pre | T es EmplaceConstructible a partir de *i en X.
| |
| Pos | std::distance(u.begin(), u.end()) == std::distance(i, j) es true.
| |||
| Expresión | Tipo | Efectos | Condiciones | |
X(std::from_range, rg)(desde C++23) |
X
|
Construye el contenedor secuencial igual, elemento por elemento, al rango rg.
|
Pre | T es EmplaceConstructible en X a partir de *ranges::begin(rg).
|
| Pos |
| |||
X(il)(desde C++11) |
X
|
Equivalente a X(il.begin(), il.end()).
|
Sin requisitos explícitos | |
a = il(desde C++11) |
X&
|
Asigna el rango representado por il a a.[2]
|
Pre | T es CopyInsertable y CopyAssignable.
|
| Pos | Los elementos existentes de a se destruyen o se asignan a.
| |||
a.emplace(p, args)(desde C++11) |
iterador
|
Inserta un objeto de tipo T, construido con std::forward<Args>(args) antes de p.
|
Pre | T es EmplaceConstructible.
|
| Pos | El iterador devuelto apunta al elemento construido a partir de args en a.
| |||
a.insert(p, t)
|
iterador
|
Inserta una copia de t antes de p.
|
Pre | T es CopyInsertable.
|
| Pos | El iterador devuelto apunta a la copia de t insertada en a.
| |||
a.insert(p, rv)(desde C++11) |
iterador
|
Inserta una copia de rv antes de p, que puede ser usando semántica de movimiento.
|
Pre | T es MoveInsertable.
|
| Pos | El iterador devuelto apunta a la copia de rv insertada en a.
| |||
a.insert(p, n, t)
|
iterador
|
Inserta n copias de t antes de p.
|
Pre | T es CopyInsertable y CopyAssignable.
|
| Pos | El iterador devuelto apunta a la copia del primer elemento insertado en a o es p para n == 0.
| |||
a.insert(p, i, j)
|
iterador
|
Inserta copias de los elementos en [i, j) antes de p.
|
Pre | T es EmplaceConstructible y, i y j no están en a.
|
| Pos |
| |||
a.insert_range(p, rg)(desde C++23) |
iterador
|
Inserta copias de los elementos en rg antes de p.
|
Pre |
|
| Pos |
| |||
a.insert(p, il)(desde C++11) |
iterador
|
Equivalente a a.insert(p, il.begin(), il.end()).
|
Pre | Sin requisitos explícitos |
| Pos | El iterador devuelto apunta a la copia del primer elemento insertado en a o es p si il está vacío.
| |||
a.erase(q)
|
iterador
|
Elimina el elemento apuntado por q.
|
Pre | Sin requisitos explícitos |
| Pos | El iterador devuelto apunta al elemento que seguía inmediatamente a q antes de la eliminación, o a.end() si dicho elemento no existe.
| |||
a.erase(q1, q2)
|
iterador
|
Elimina los elementos en [q1, q2).
|
Pre | Sin requisitos explícitos |
| Pos | El iterador devuelto apunta al elemento apuntado por q2 antes de la eliminación, o a.end() si dicho elemento no existe.
| |||
a.clear()
|
void
|
Destruye todos los elementos de a.
|
Pre | Sin requisitos explícitos |
| Pos |
| |||
a.assign(i, j)
|
void
|
Reemplaza los elementos en a con una copia de [i, j).
|
Pre |
|
| Pos | Cada iterador en [i, j) se desreferencia una vez.
| |||
a.assign_range(rg)(desde C++23) |
void
|
Reemplaza los elementos en a con una copia de cada elemento en rg.
|
Pre |
|
| Pos |
| |||
a.assign(il)(desde C++11) |
void
|
Equivalente a a.assign(il.begin(), il.end()).
|
Sin requisitos explícitos | |
a.assign(n, t)
|
void
|
Reemplaza elementos es a con n copias de t.
|
Pre | T es CopyInsertable y CopyAssignable.
|
| Pos | Sin requisitos explícitos | |||
| Notas | ||||
| ||||
Operaciones opcionales
Las siguientes expresiones deben ser válidas y tener su efectos especificados para los contenedores de secuencia nombrados, todas las operaciones excepto prepend_range y append_range (desde C++23) tienen tiempo constante amortizado:
| Expresión | Tipo | Efectos | Precondiciones[1] | Contenedores |
|---|---|---|---|---|
a.front()
|
referencia, o
|
Devuelve *a.begin().
|
Sin requisitos explícitos | std::basic_string, std::array, std::deque, std::forward_list, std::inplace_vector, std::list, std::vector |
a.back()
|
referencia, o
|
Equivalente a auto tmp = a.end();--tmp;return *tmp;.
|
Sin requisitos explícitos | std::basic_string, std::array, std::deque, std::inplace_vector, std::list, std::vector |
a.emplace_front(args)(desde C++11) |
void
|
Inserta al principio una Tconstruida con std::forward<Args> (args)....
|
T es EmplaceConstructible en X a partir de args.
|
std::deque, std::forward_list, std::list |
a.emplace_back(args)(desde C++11) |
void
|
Inserta al final una Tconstruida con std::forward<Args> (args)....
|
T es EmplaceConstructible en X a partir de args.
|
std::deque, std::inplace_vector, std::list, std::vector |
a.push_front(t)
|
void
|
Inserta al principio una copia de t.
|
T es CopyInsertable en X.
|
std::deque, std::forward_list, std::list |
a.push_front(rv)(desde C++11) |
void
|
Inserta al principio una copia de rv, que puede ser mediante semántica de movimiento.
|
T es MoveInsertable en X.
| |
a.prepend_range(rg)(desde C++23) |
void
|
Inserta[2] copias de elementos en rg antes de begin(), cada iterador en rg se desreferencia una vez.
|
T es EmplaceConstructible en X a partir de *ranges::begin(rg).
|
std::deque, std::forward_list, std::list |
a.push_back(t)
|
void
|
Inserta al final una copia de t.
|
T es CopyInsertable en X.
|
std::basic_string, std::deque, std::inplace_vector, std::list, std::vector |
a.push_back(rv)(desde C++11) |
void
|
Inserta al final una copia de rv, que puede ser mediante semántica de movimiento.
|
T es MoveInsertable en X.
| |
a.append_range(rg)(desde C++23) |
void
|
Inserta[2] copias de los elementos en rg antes de end() desreferenciando cada iterador en rg una vez.
|
T es EmplaceConstructible en X a partir de *ranges::begin(rg).
|
std::deque, std::inplace_vector, std::list, std::vector |
a.pop_front()
|
void
|
Destruye el primer elemento. | a.empty() es false.
|
std::deque, std::forward_list, std::list |
a.pop_back()
|
void
|
Destruye el último elemento. | a.empty() es false.
|
std::basic_string, std::deque, std::inplace_vector, std::list, std::vector |
a[n]
|
referencia, o
|
Equivalente a return *(a.begin() + n);.
|
Sin requisitos explícitos | std::basic_string, std::array, std::deque, std::inplace_vector, std::vector |
a.at(n)
|
referencia, o
|
Devuelve *(a.begin() + n), lanza excepción std::out_of_range si n >= size().
|
Sin requisitos explícitos | |
| Notas | ||||
| ||||
Además, para cada contenedor de secuencia:
- Una plantilla de constructor que toma dos iteradores de entrada y sobrecarga las funciones miembro de plantilla
insert,append,assign,replaceque toman dos iteradores de entrada no participan en la resolución de sobrecarga si el argumento de plantilla correspondiente no satisafce InputIterator.
|
(desde C++17) |
Contenedores secuenciales en la biblioteca estándar
| Almacena y manipula secuencias de caracteres. (plantilla de clase) | |
(C++11) |
Array estático contiguo. (plantilla de clase) |
| Array dinámico contiguo. (plantilla de clase) | |
(C++26) |
array contiguo in situ, de capacidad fija y redimensionable dinámicamente (plantilla de clase) |
Cola doblemente terminada (deque). (plantilla de clase) | |
(desde C++11) |
Lista enlazada. (plantilla de clase) |
| Lista doblemente enlazada. (plantilla de clase) |
Concesiones / notas de uso
| std::vector | Acceso rápido, pero inserciones/eliminaciones mayoritariamente ineficientes. |
| std::inplace_vector | Acceso rápido, almacenamiento local contiguo, pero capacidad fija e inserciones/eliminaciones mayoritariamente ineficientes. |
| std::array | Acceso rápido, almacenamiento local contiguo, pero número fijo de elementos y no tiene inserción/eliminación. |
| std::deque | Acceso rápido, inserción/eliminación eficiente al inicio/final pero no en medio de la secuencia. |
| std::list std::forward_listInserción/eliminación eficiente en medio de la secuencia, pero acceso en tiempo lineal mayoritariamente | |
Informe de defectos
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
| ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 139 | C++98 | no era necesario implementar las operaciones opcionales para los contenedores designados |
requerido con tiempo amortizado |
| LWG 149 | C++98 | a.insert(p, t) devolvía un iterador mientras quea.insert(p, n, t) y a.insert(p, n, t) devolvían void
|
Todos devuelven uniterador
|
| LWG 151 | C++98 | Se requería que q1 fuera desreferenciable[1]
|
puede no ser desreferenciable |
| LWG 355 | C++98 | llamar a a.back() o a.pop_back() ejecutaría--a.end(), lo cual es peligroso[2]
|
decrementa una copia de a.end() en su lugar
|
| LWG 589 | C++98 | los elementos a los que hacen referencia i y jpodrían no ser convertibles a value_type
|
son implícitamente convertibles a value_type
|
| LWG 3927 | C++98 | operator[] no tenía ningún requisito implícito
|
se añadió el requisito implícito |
- ↑ Esto es un defecto porque hace que el comportamiento de
a.erase(a.begin(), a.end())sea indefinido siaes un contenedor vacío. - ↑ Si el tipo de
a.end()es un tipo fundamental,--a.end()está mal formado. Es peligroso cunado el tipo deaestá basado en una plantilla, en este caso, puede resultar dificil encontrar este error.