最終更新日時:
が更新

履歴 編集

テンプレートテンプレートパラメータのパックへのインデックスアクセスを許可 [P3670R4](C++29)

このページはC++29に採用された言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

概要

C++29では、C++26で導入されたパラメータパックへの添字アクセスを、テンプレートテンプレートパラメータのパック(テンプレート名のパック)に対しても使用できるようになる。

template <template <typename> typename... TT>
struct S {
  template <typename T>
  using First = TT...[0]<T>;
};

TT...[N]はテンプレート名として扱われ、テンプレート名を書けるあらゆる場所で使用できる。クラステンプレートのテンプレートテンプレートパラメータに加えて、C++26で導入された変数テンプレート・コンセプトのテンプレートテンプレートパラメータのパックにも適用できる。

仕様

  • 添字アクセスP...[N]Pはパックを表すテンプレート名であること
  • 添字Nstd::size_t型へ変換された定数式であり、その値V0 <= V < sizeof...(P)の範囲であること。P...[V]は、パックのV番目のテンプレート名を表す
  • P...[N]自体はパック展開であり、パターンはテンプレート名である
  • P...[N]がクラステンプレートやエイリアステンプレートを表す場合は、クラステンプレートのテンプレート引数推論にも使用できる

#include <iostream>
#include <list>
#include <vector>

template <template <class> class... TT>
struct S {
  // パックTTの先頭のテンプレートを、テンプレート名として使用する
  template <class T>
  using First = TT...[0]<T>;
};

int main()
{
  // TT...[0]std::vectorを指すため、First<int>はstd::vector<int>
  S<std::vector, std::list>::First<int> v = {1, 2, 3};
  std::cout << v[1] << std::endl;
}

出力

2

この機能が必要になった背景・経緯

C++26のパラメータパックへの添字アクセス (P2662R3) は、型のパックと式のパックのみを対象としており、テンプレート名のパックには使用できなかった。設計としてはすべてのパックに添字アクセスできることを意図していたが、当時審議中だったコンセプトと変数テンプレートをテンプレート引数として渡せるようにする提案 (P2841) などとの相互作用が明確でなかったため、テンプレート名のパックは見送られていた。

P2841がテンプレート名のパックへの添字アクセスの設計に影響しないことが確認されたため、本提案によってパック添字アクセスの設計が完成された。

関連項目

参照