std::span
| Definido en el archivo de encabezado <span>
|
||
template< typename T, std::size_t Extent = std::dynamic_extent > class span; |
(desde C++20) | |
La plantilla de clase span o lapso describe un objeto que puede referirse a una secuencia contigua de objetos con el primer elemento de la secuencia en la posición cero. Un lapso (span) puede tener ya sea un alcance (extent) estático, en cuyo caso el número de elementos en la secuencia se conoce y está codificado en el tipo, o un alcance dinámico.
Si un span tiene un alcance dinámico, una implementación típica mantiene solamente dos miembros: un puntero a T y un tamaño.
Un span con un alcance estático puede tener solamente un miembro: un puntero a T.
|
Toda especialización de |
(desde C++23) |
Parámetros de plantilla
| T | - | Tipo de elemento; debe ser un tipo completo que no es un tipo de clase abstracta. |
| Extent | - | El número de elementos en la secuencia, o std::dynamic_extent si es dinámico.
|
Tipos miembro
| Tipo miembro | Definición |
element_type
|
T
|
value_type
|
std::remove_cv_t<T>
|
size_type
|
std::size_t |
difference_type
|
std::ptrdiff_t |
pointer
|
T*
|
const_pointer
|
const T*
|
reference
|
T&
|
const_reference
|
const T&
|
iterator
|
RandomAccessIterator definido por la implementación, ConstexprIterator, y contiguous_iterator cuyo value_type es value_type
|
reverse_iterator
|
std::reverse_iterator<iterator>
|
Nota: iterator es un iterador mutable si T no está calificado const.
Todos los requerimientos de los tipos de iterador de un Container también se aplican al tipo iterator de span.
Constante miembro
<tbody> </tbody> static constexpr std::size_t extent = Extent; |
||
Funciones miembro
Construye un lapso (span). (función miembro pública) | |
| Asigna un lapso. (función miembro pública) | |
Iteradores | |
(C++20) |
Devuelve un iterador al principio. (función miembro pública) |
(C++20) |
Devuelve un iterador al final. (función miembro pública) |
(C++20) |
Devuelve un iterador inverso al principio. (función miembro pública) |
| Devuelve un iterador inverso al final. (función miembro pública) | |
Acceso a elementos | |
(C++20) |
Accede al primer elemento. (función miembro pública) |
(C++20) |
Accede al último elemento. (función miembro pública) |
| Accede a un elemento de la secuencia. (función miembro pública) | |
| Devuelve un puntero al inicio de la secuencia de elementos. (función miembro pública) | |
Observadores | |
| Devuelve el número de elementos en la secuencia. (función miembro pública) | |
| Devuelve el tamaño de la secuencia en bytes. (función miembro pública) | |
| Comprueba si la secuencia está vacía (función miembro pública) | |
Subvistas | |
| Obtiene un sublapso que consiste en los primeros N elementos de la secuencia. (función miembro pública) | |
| Obtiene un sublapso que consiste en los últimos N elementos de la secuencia. (función miembro pública) | |
| Obtiene un sublapso. (función miembro pública) | |
Funciones no miembro
Convierte un lapso (span) en una vista de sus bytes subyacentes. (plantilla de función) |
Constante no miembro
(C++20) |
Una constante de tipo size_t que significa que el lapso tiene alcance dinámico. (constante) |
Plantillas auxiliares
<tbody> </tbody> template<class T, std::size_t Extent> inline constexpr bool ranges::enable_borrowed_range<std::span<T, Extent>> = true; |
||
Esta especialización de ranges::enable_borrowed_range hace que un lapso (span) satisfaga a borrowed_range.
template<class T, std::size_t Extent> inline constexpr bool ranges::enable_view<std::span<T, Extent>> = true; |
||
Esta especialización de ranges::enable_view hace que un lapso (span) satisfaga a view.
Guías de deducción
Notas
Las especializaciones de std::span ya son tipos trivialmente copiables en todas las implementaciones en existencia, incluso antes de que se introdujera el requerimiento formal en C++23.
Ejemplo
El ejemplo usa std::span para implementar algunos algoritmos en rangos contiguos.
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <span>
template<class T, std::size_t N> [[nodiscard]]
constexpr auto slide(std::span<T,N> s, std::size_t offset, std::size_t width) {
return s.subspan(offset, offset + width <= s.size() ? width : 0U);
}
template<class T, std::size_t N, std::size_t M> [[nodiscard]]
constexpr bool starts_with(std::span<T,N> data, std::span<T,M> prefix) {
return data.size() >= prefix.size()
&& std::equal(prefix.begin(), prefix.end(), data.begin());
}
template<class T, std::size_t N, std::size_t M> [[nodiscard]]
constexpr bool ends_with(std::span<T,N> data, std::span<T,M> suffix) {
return data.size() >= suffix.size()
&& std::equal(data.end() - suffix.size(), data.end(),
suffix.end() - suffix.size());
}
template<class T, std::size_t N, std::size_t M> [[nodiscard]]
constexpr bool contains(std::span<T,N> span, std::span<T,M> sub) {
return std::search(span.begin(), span.end(), sub.begin(), sub.end()) != span.end();
// return std::ranges::search(span, sub).begin() != span.end();
}
void print(const auto& seq) {
for (const auto& elem : seq) std::cout << elem << ' ';
std::cout << '\n';
}
int main()
{
constexpr int a[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
constexpr int b[] { 8, 7, 6 };
for (std::size_t offset{}; ; ++offset) {
constexpr std::size_t width{6};
auto s = slide(std::span{a}, offset, width);
if (s.empty())
break;
print(s);
}
static_assert(starts_with(std::span{a}, std::span{a,4})
&& starts_with(std::span{a+1, 4}, std::span{a+1,3})
&& !starts_with(std::span{a}, std::span{b})
&& !starts_with(std::span{a,8}, std::span{a+1,3})
&& ends_with(std::span{a}, std::span{a+6,3})
&& !ends_with(std::span{a}, std::span{a+6,2})
&& contains(std::span{a}, std::span{a+1,4})
&& !contains(std::span{a,8}, std::span{a,9}));
}
Salida:
0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
Informes 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 |
|---|---|---|---|
| P2325R3 | C++20 | Los span de alcance estático distinto de cero no eran una vista (view)
|
Lo son, ya que default_initializable no se requiere.
|
Véase también
(C++11) |
Permite el uso de la sintaxis de inicialización de lista para inicializar tipos de datos no simples (plain-old data types). (plantilla de clase) |
(C++17) |
Vista sobre cadena de solo lectura. (plantilla de clase) |
(C++20) |
Combina un par iterador-centinela en una vista (view). (plantilla de clase) |