C++
станд :: integer_sequence
Поиск…
Вступление
std::integer_sequence<Type, Values...>
представляет последовательность значений типа Type
где Type
является одним из встроенных целочисленных типов. Эти последовательности используются при реализации шаблонов классов или функций, которые извлекают выгоду из позиционного доступа. Стандартная библиотека также содержит «фабричные» типы, которые создают восходящие последовательности целочисленных значений только из числа элементов.
Поверните std :: tuple в функциональные параметры
std::tuple<T...>
может использоваться для передачи нескольких значений. Например, его можно использовать для хранения последовательности параметров в какой-то форме очереди. При обработке такого кортежа его элементы должны быть превращены в аргументы вызова функции:
#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 });
}
Пока класс поддерживает std::get<I>(object)
и std::tuple_size<T>::value
он может быть расширен с помощью указанной выше функции process()
. Сама функция полностью не зависит от количества аргументов.
Создайте пакет параметров, состоящий из целых чисел
Сама std::integer_sequence
- это сохранение последовательности целых чисел, которая может быть преобразована в пакет параметров. Его основной ценностью является возможность создания шаблонов класса «фабрика», создающих эти последовательности:
#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()
функции print_sequence()
используется std::initializer_list<bool>
при расширении целочисленной последовательности, чтобы гарантировать порядок оценки и не создавать неиспользуемую переменную [array].
Поверните последовательность индексов в копии элемента
Развертывание пакета параметров индексов в выражении запятой со значением создает копию значения для каждого из индексов. К сожалению, gcc
и clang
считают, что индекс не имеет никакого эффекта и предупреждает об этом ( gcc
можно заставить замолчать, указав индекс на 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";
}