C++
std :: integer_sequence
Buscar..
Introducción
std::integer_sequence<Type, Values...>
representa una secuencia de valores de tipo Type
donde Type
es uno de los tipos de enteros incorporados. Estas secuencias se utilizan al implementar plantillas de clase o función que se benefician del acceso posicional. La biblioteca estándar también contiene tipos "de fábrica" que crean secuencias ascendentes de valores enteros solo a partir del número de elementos.
Gire un std :: tuple en parámetros de función
Se puede usar un std::tuple<T...>
para pasar varios valores. Por ejemplo, podría usarse para almacenar una secuencia de parámetros en alguna forma de una cola. Al procesar tal tupla, sus elementos deben convertirse en argumentos de llamada de función:
#include <array>
#include <iostream>
#include <string>
#include <tuple>
#include <utility>
// ----------------------------------------------------------------------------
// Example functions to be called:
void f(int i, std::string const& s) {
std::cout << "f(" << i << ", " << s << ")\n";
}
void f(int i, double d, std::string const& s) {
std::cout << "f(" << i << ", " << d << ", " << s << ")\n";
}
void f(char c, int i, double d, std::string const& s) {
std::cout << "f(" << c << ", " << i << ", " << d << ", " << s << ")\n";
}
void f(int i, int j, int k) {
std::cout << "f(" << i << ", " << j << ", " << k << ")\n";
}
// ----------------------------------------------------------------------------
// The actual function expanding the tuple:
template <typename Tuple, std::size_t... I>
void process(Tuple const& tuple, std::index_sequence<I...>) {
f(std::get<I>(tuple)...);
}
// The interface to call. Sadly, it needs to dispatch to another function
// to deduce the sequence of indices created from std::make_index_sequence<N>
template <typename Tuple>
void process(Tuple const& tuple) {
process(tuple, std::make_index_sequence<std::tuple_size<Tuple>::value>());
}
// ----------------------------------------------------------------------------
int main() {
process(std::make_tuple(1, 3.14, std::string("foo")));
process(std::make_tuple('a', 2, 2.71, std::string("bar")));
process(std::make_pair(3, std::string("pair")));
process(std::array<int, 3>{ 1, 2, 3 });
}
Siempre que una clase admita std::get<I>(object)
y std::tuple_size<T>::value
se puede expandir con la función process()
. La función en sí es totalmente independiente del número de argumentos.
Crear un paquete de parámetros que consiste en enteros.
std::integer_sequence
sí mismo consiste en mantener una secuencia de enteros que se pueden convertir en un paquete de parámetros. Su valor principal es la posibilidad de crear plantillas de clase "de fábrica" creando estas secuencias:
#include <iostream>
#include <initializer_list>
#include <utility>
template <typename T, T... I>
void print_sequence(std::integer_sequence<T, I...>) {
std::initializer_list<bool>{ bool(std::cout << I << ' ')... };
std::cout << '\n';
}
template <int Offset, typename T, T... I>
void print_offset_sequence(std::integer_sequence<T, I...>) {
print_sequence(std::integer_sequence<T, T(I + Offset)...>());
}
int main() {
// explicitly specify sequences:
print_sequence(std::integer_sequence<int, 1, 2, 3>());
print_sequence(std::integer_sequence<char, 'f', 'o', 'o'>());
// generate sequences:
print_sequence(std::make_index_sequence<10>());
print_sequence(std::make_integer_sequence<short, 10>());
print_offset_sequence<'A'>(std::make_integer_sequence<char, 26>());
}
La plantilla de la función print_sequence()
usa un std::initializer_list<bool>
al expandir la secuencia de enteros para garantizar el orden de evaluación y no crear una variable [array] no utilizada.
Convertir una secuencia de índices en copias de un elemento.
La expansión del paquete de parámetros de índices en una expresión de coma con un valor crea una copia del valor para cada uno de los índices. Lamentablemente, gcc
y el clang
pensar en el índice no tiene ningún efecto y advertir de ello ( gcc
se puede silenciar el índice de fundición a void
):
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <string>
#include <utility>
template <typename T, std::size_t... I>
std::array<T, sizeof...(I)> make_array(T const& value, std::index_sequence<I...>) {
return std::array<T, sizeof...(I)>{ (I, value)... };
}
template <int N, typename T>
std::array<T, N> make_array(T const& value) {
return make_array(value, std::make_index_sequence<N>());
}
int main() {
auto array = make_array<20>(std::string("value"));
std::copy(array.begin(), array.end(),
std::ostream_iterator<std::string>(std::cout, " "));
std::cout << "\n";
}