サーチ…


前書き

クラステンプレートstd::integer_sequence<Type, Values...>は、タイプTypeの値のシーケンスを表します。 Typeは、組み込み整数タイプの1つです。これらのシーケンスは、位置アクセスの恩恵を受けるクラスまたは関数テンプレートを実装するときに使用されます。標準ライブラリには、要素数から整数値の昇順シーケンスを作成する「ファクトリ」型も含まれています。

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()関数テンプレートは、整数シーケンスを展開するときにstd::initializer_list<bool>して、評価の順序を保証し、未使用の[配列]変数を作成しません。

一連のインデックスを要素のコピーに変換する

カンマ式のインデックスのパラメータパックを値で展開すると、各インデックスの値のコピーが作成されます。悲しいことに、 gccclangはインデックスが効果がなく、警告をclangと考えています( gccはインデックスをvoidキャストしてサイレントにすることができ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
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow