Sök…


Introduktion

std::integer_sequence<Type, Values...> representerar en sekvens av värden av typ Type där Type är en av de inbyggda heltalstyperna. Dessa sekvenser används vid implementering av klass- eller funktionsmallar som drar nytta av positionsåtkomst. Standardbiblioteket innehåller också "fabrik" -typer som skapar stigande sekvenser med heltal bara från antalet element.

Vrid en std :: tupel till funktionsparametrar

En std::tuple<T...> kan användas för att skicka flera värden runt. Till exempel kan den användas för att lagra en sekvens av parametrar i någon form av en kö. Vid bearbetning av en sådan tupel måste dess element förvandlas till funktionssamtalargument:

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

Så länge en klass stöder std::get<I>(object) och std::tuple_size<T>::value kan den utvidgas med ovanstående process() -funktion. Funktionen i sig är helt oberoende av antalet argument.

Skapa ett parameterpaket som består av heltal

std::integer_sequence handlar om att hålla en sekvens av heltal som kan förvandlas till ett parameterpaket. Det primära värdet är möjligheten att skapa "fabrik" klassmallar som skapar dessa sekvenser:

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

print_sequence() använder en std::initializer_list<bool> vid utökning av heltalssekvensen för att garantera utvärderingsordningen och inte skapa en oanvänd variabel [array].

Förvandla en sekvens av index till kopior av ett element

Att utöka parameterpaketet med index i ett kommauttryck med ett värde skapar en kopia av värdet för vart och ett av indexen. Tyvärr tror gcc och clang att indexet inte har någon effekt och varnar för det ( gcc kan tystas genom att indexet blir 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow