Szukaj…


Wprowadzenie

Szablon klasy std::integer_sequence<Type, Values...> reprezentuje sekwencję wartości typu Type gdzie Type jest jednym z wbudowanych typów całkowitych. Sekwencje te są używane przy wdrażaniu szablonów klas lub funkcji, które korzystają z dostępu pozycyjnego. Biblioteka standardowa zawiera również typy „fabryczne”, które tworzą rosnące sekwencje wartości całkowitych tylko na podstawie liczby elementów.

Włącz std :: krotkę w parametry funkcji

std::tuple<T...> może służyć do przekazywania wielu wartości. Na przykład można go użyć do przechowywania sekwencji parametrów w jakiejś formie kolejki. Podczas przetwarzania takiej krotki należy przekształcić jej elementy w argumenty wywołania funkcji:

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

Tak długo, jak klasa obsługuje wartości std::get<I>(object) i std::tuple_size<T>::value , można ją rozszerzyć o powyższą funkcję process() . Sama funkcja jest całkowicie niezależna od liczby argumentów.

Utwórz pakiet parametrów składający się z liczb całkowitych

Sam parametr std::integer_sequence polega na utrzymywaniu sekwencji liczb całkowitych, które można przekształcić w pakiet parametrów. Jego podstawową wartością jest możliwość tworzenia szablonów klas „fabrycznych”, tworząc następujące sekwencje:

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

Szablon funkcji print_sequence() korzysta ze std::initializer_list<bool> podczas rozwijania sekwencji liczb całkowitych, aby zagwarantować kolejność obliczeń i nie tworzyć nieużywanej zmiennej [tablica].

Zamień sekwencję indeksów w kopie elementu

Rozszerzenie pakietu parametrów indeksów w wyrażeniu przecinkowym o wartość tworzy kopię wartości dla każdego z indeksów. Niestety, gcc i clang sądzą, że indeks nie ma żadnego efektu i ostrzegają przed nim ( gcc można wyciszyć, rzutując indeks na 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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow