Recherche…


Introduction

Le modèle de classe std::integer_sequence<Type, Values...> représente une séquence de valeurs de type TypeType est l'un des types entiers intégrés. Ces séquences sont utilisées lors de l'implémentation de modèles de classe ou de fonction bénéficiant d'un accès positionnel. La bibliothèque standard contient également des types "factory" qui créent des séquences ascendantes de valeurs entières à partir du nombre d'éléments.

Tournez un std :: tuple en paramètres de fonction

Un std::tuple<T...> peut être utilisé pour transmettre plusieurs valeurs. Par exemple, il pourrait être utilisé pour stocker une séquence de paramètres dans une forme de file d'attente. Lors du traitement d'un tel tuple, ses éléments doivent être transformés en arguments d'appel de fonction:

#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 });
}

Tant qu'une classe supporte std::get<I>(object) et std::tuple_size<T>::value elle peut être développée avec la fonction process() ci-dessus. La fonction elle-même est entièrement indépendante du nombre d'arguments.

Créer un pack de paramètres composé d'entiers

std::integer_sequence lui-même consiste à maintenir une séquence d'entiers pouvant être transformée en un paquet de paramètres. Sa principale valeur est la possibilité de créer des modèles de classe "factory" en créant ces séquences:

#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>());
}

Le modèle de fonction print_sequence() utilise un std::initializer_list<bool> lors de l'extension de la séquence entière pour garantir l'ordre d'évaluation et ne pas créer de variable [array] inutilisée.

Transforme une séquence d'indices en copies d'un élément

L'extension du paquet de paramètres d'index dans une expression virgule avec une valeur crée une copie de la valeur pour chacun des index. Malheureusement, gcc et clang pense que l'indice n'a pas d' effet et mettre en garde à ce sujet ( gcc peut être réduit au silence par coulée l'indice d' 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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow