N3658 Compile-time integer sequences
C++14では、
// <utility> namespace std { template<class T, T...> struct integer_sequence; template<size_t... I> using index_sequence = integer_sequence<size_t, I...>; template<class T, T N> using make_integer_sequence = integer_sequence<T, see below>; template<size_t N> using make_index_sequence = make_integer_sequence<size_t, N>; template<class... T> using index_sequence_for = make_index_sequence<sizeof...(T)>; }
make_integer_sequence
とすると、integer_sequence
という型が出来上がります。
これは、たとえばタプルを展開するときに使用します。以下は、関数f()
に、タプルを展開して引数として渡すapply()
関数の実装です。
#include <iostream> #include <tuple> #include <utility> template<typename F, typename Tuple, size_t... I> auto apply_(F&& f, Tuple&& args, std::index_sequence<I...>) { return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...); } template<typename F, typename Tuple, typename Indices = std::make_index_sequence<std::tuple_size<Tuple>::value>> auto apply(F&& f, Tuple&& args) { return apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices()); } void f(int a, char b, double c) { std::cout << a << std::endl << b << std::endl << c << std::endl; } int main() { apply(f, std::make_tuple(3, 'a', 3.14)); }
3 a 3.14
integer_sequence
の各値を、タプルの添字として使用し、それをタプルの全要素に適用することで、「tuple(3, 'a', 3.14)
」を「3, 'a', 3.14
」に展開しています。
この提案には、ボレロ村上さん(id:boleros)の貢献によって、「効率に関する考察(Efficiency considerations)」の項が追加されています。詳細は、彼のブログを参照してください。
C++ 標準ライブラリにテンプレート再帰深度のオーダーを定めるべきである - ボレロ村上 - ENiyGmaA Code
ISO C++ Standard - Future Proposals に投稿した - ボレロ村上 - ENiyGmaA Code