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.
Contenido |
[editar] 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
X
satisface 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 | ||||
|
[editar] 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 T construida 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 T construida 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
,replace
que 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) |
[editar] 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) |
[editar] 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 |
[editar] 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 j podrí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 si a es un contenedor vacío.
- ↑ Si el tipo de a.end() es un tipo fundamental, --a.end() está mal formado. Es peligroso cunado el tipo de a está basado en una plantilla, en este caso, puede resultar dificil encontrar este error.