Buscar..


Introducción

La plantilla de clase 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";
}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow