yohhoyの日記

技術的メモをしていきたい日記

index_tupleイディオム もしくは The Indices Trick

C++においてタプル型に格納された可変個の値を、関数呼び出しの実引数などに展開するイディオム。C++14標準ライブラリでは同イディオムをサポートするstd::index_sequence, std::make_index_sequenceが提供される。

// C++14以降
#include <utility>
#include <tuple>

template<typename... Ts>
class Holder {
  std::tuple<Ts...> t_;
public:
  Holder(Ts... args)
    // 引数args...をタプル型tuple<Ts...>に格納する
    : t_(args...) {}

  void operator()() {
    // 可変長テンプレートパラメータTsの要素数から
    // インデクス列を表現するindex_sequence型を生成する
    call_impl(std::make_index_sequence<sizeof...(Ts)>{});
    // 例: Ts要素数が3ならindex_sequence<0,1,2>型を生成
  }

private:
  template<std::size_t... Is>
  void call_impl(std::index_sequence<Is...>) {
    func(std::get<Is>(t_)...);
    // 例: Is=[1,2,3]つまりindex_sequence<0,1,2>型ならば
    // func(std::get<0>(t_), std::get<1>(t_), std::get<2>(t_));
    // とコンパイル時に展開される
  }
};
Holder<int> g(42);
g();  // func(42)を呼び出す

Holder<double, double> h(3.14, -0.5);
h();  // func(3.14, -0.5)を呼び出す

日本語圏では "index_tupleイディオム" として言及されることが多い。Sproutライブラリ作者の id:boleros さんが事実上の名付け親(かな?)。

一方、英語圏(主にStack Overflow)では "The Indices Trick" として言及されることが多い様子。*1

関連URL:

*1:余談:本記事はStack Overflowで回答を書こうと思って調べたのがきっかけ。