std::tuple_size
From cppreference.com
| ヘッダー <array> で定義 |
||
| ヘッダ <tuple> で定義 |
||
| ヘッダ <utility> で定義 |
||
| ヘッダ <ranges> で定義 |
(C++20以降) |
|
| ヘッダ <complex> で定義 |
(C++26以降) |
|
| template< class T > struct tuple_size; // 未定義 |
(1) | (C++11以降) |
| template< class T > struct tuple_size< const T > |
(2) | (C++11以降) |
| template< class T > struct tuple_size< volatile T > |
(3) | (C++11以降) (C++20で非推奨) |
| template< class T > struct tuple_size< const volatile T > |
(4) | (C++11以降) (C++20で非推奨) |
コンパイル時定数式として、タプルライクな型の要素数にアクセスを提供します。
1) プライマリテンプレートは定義されていません。型をタプルライクにするには、明示的な(完全な)または部分的な特殊化が必要です。
2-4) cv修飾された型に対する特殊化は、デフォルトでは対応するcv非修飾バージョンからvalueを再利用します。
|
(2-4) はSFINAEフレンドリーです。もしstd::tuple_size<T>::valueが評価されないオペランドとして扱われた場合にill-formedであるならば、それらはメンバvalueを提供しません。アクセスチェックは、 #include <utility> struct X { int a, b; }; const auto [x, y] = X(); // structured binding declaration first attempts // tuple_size<const X> which attempts to use tuple_size<X>::value, // then soft error encountered, binds to public data members |
(C++17以降) |
目次 |
[編集] 特殊化
標準ライブラリは、標準ライブラリ型に対して以下の特殊化を提供します。
| (C++11) |
のサイズを取得する
|
| (C++11) |
pairのサイズを取得する(クラステンプレート特殊化) |
| (C++11) |
array のサイズを取得する(クラステンプレート特殊化) |
| std::ranges::subrangeのサイズを取得する (クラステンプレート特殊化) | |
| std::complexのサイズを取得します。 (クラステンプレートの特殊化) |
std::tuple_sizeのすべての特殊化は、あるNに対してstd::integral_constant<std::size_t, N>という基底特性でUnaryTypeTraitを満たします。
ユーザは、プログラム定義型をタプルライクにするためにstd::tuple_sizeを特殊化できます。プログラム定義の特殊化は上記の要件を満たす必要があります。
通常、カスタマイズが必要なのはcv非修飾型に対する特殊化のみです。
[編集] ヘルパー変数テンプレート
| ヘッダ <tuple> で定義 |
||
| template< class T > constexpr std::size_t tuple_size_v = tuple_size<T>::value; |
(C++17以降) | |
std::integral_constant から継承
メンバ定数
| value [static] |
標準特殊化の場合、タプルライクな型Tの要素数(公開静的メンバ定数) |
メンバ関数
| operator std::size_t |
オブジェクトを std::size_t に変換し、value を返します。 (public member function) |
| operator() (C++14) |
value を返します。 (public member function) |
メンバ型
| 型 | 定義 |
value_type
|
std::size_t |
type
|
std::integral_constant<std::size_t, value> |
[編集] 例
このコードを実行
#include <array> #include <cstddef> #include <ranges> #include <tuple> #include <utility> template<class T, std::size_t Size> struct Arr { T data[Size]; }; // Program-defined specialization of std::tuple_size: template<class T, std::size_t Size> struct std::tuple_size<Arr<T, Size>> : public integral_constant<std::size_t, Size> {}; int main() { using tuple1 = std::tuple<int, char, double>; static_assert(3 == std::tuple_size_v<tuple1>); // uses using template (C++17) using array3x4 = std::array<std::array<int, 3>, 4>; static_assert(4 == std::tuple_size<array3x4>{}); // uses operator std::size_t using pair = std::pair<tuple1, array3x4>; static_assert(2 == std::tuple_size<pair>()); // uses operator() using sub = std::ranges::subrange<char*, char*>; static_assert(2 == std::tuple_size<sub>::value); using Arr5 = Arr<int, 5>; static_assert(5 == std::tuple_size_v<Arr5>); }
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2212 | C++11 | cv型に対する特殊化が一部のヘッダーで要求されておらず、曖昧さを生じていた。 | 必要 |
[編集] 関連項目
| 構造化束縛 (C++17) | 指定された名前を初期化子のサブオブジェクトまたはタプル要素に束縛します |
| (C++11) |
タプルライクな型の要素型を取得する (クラステンプレート) |
| (C++11) |
任意の数のタプルを連結して tuple を生成する(関数テンプレート) |