Namespaces
Variants

std:: tuple_element

From cppreference.net
Utilities library
ヘッダーで定義 <tuple>
ヘッダーで定義 <array>
ヘッダーで定義 <utility>
ヘッダーで定義 <ranges>
(C++20以降)
ヘッダーで定義 <complex>
(C++26以降)
template < std:: size_t I, class T >
struct tuple_element ; // 定義なし
(1) (C++11以降)
template < std:: size_t I, class T >

struct tuple_element < I, const T > {
using type = typename
std:: add_const < typename std :: tuple_element < I, T > :: type > :: type ;

} ;
(2) (C++11以降)
template < std:: size_t I, class T >

struct tuple_element < I, volatile T > {
using type = typename
std:: add_volatile < typename std :: tuple_element < I, T > :: type > :: type ;

} ;
(3) (C++11以降)
(C++20で非推奨)
template < std:: size_t I, class T >

struct tuple_element < I, const volatile T > {
using type = typename
std:: add_cv < typename std :: tuple_element < I, T > :: type > :: type ;

} ;
(4) (C++11以降)
(C++20で非推奨)

tuple-like 型の要素の型に対して、コンパイル時のインデックス付きアクセスを提供します。

1) プライマリテンプレートは定義されていません。型をタプルライクにするには、明示的(完全)または部分的な特殊化が必要です。
2-4) cv修飾型に対する特殊化は、デフォルトで対応するcv修飾子を単に追加する。

std::tuple_element はコア言語と連携します:タプルライクなケースで 構造化バインディング のサポートを提供できます。

(C++17以降)

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - C++関連の専門用語(Specializations、Member types、Helper types、Notes、Example、Defect reports、See also)は原文のまま保持しました - HTMLタグ、属性、クラス名、ID、リンク先は一切変更していません - 数値や書式設定は完全に保持されています

特殊化

標準ライブラリは、標準ライブラリ型に対して以下の特殊化を提供します:

指定された要素の型を取得する
(クラステンプレートの特殊化)
pair の要素の型を取得する
(クラステンプレートの特殊化)
array の要素の型を取得する
(クラステンプレートの特殊化)
std::ranges::subrange のイテレータまたは番兵の型を取得する
(クラステンプレートの特殊化)
std::complex の基礎となる実数部と虚数部の型を取得する
(クラステンプレートの特殊化)

ユーザーはプログラム定義型に対して std::tuple_element を特殊化し、それらをtuple-likeにすることができます。

通常の場合、 get 関数が参照メンバーまたはサブオブジェクトへの参照を返す場合、cv修飾されていない型に対する特殊化のみをカスタマイズする必要があります。

メンバー型

メンバー型 定義
type 標準特殊化の場合、 tuple-like T I 番目 の要素の型。ここで I [ 0 , std:: tuple_size < T > :: value ) の範囲内

ヘルパー型

ヘッダーで定義 <tuple>
template < std:: size_t I, class T >
using tuple_element_t = typename tuple_element < I, T > :: type ;
(C++14以降)

注記

機能テスト マクロ 標準 機能
__cpp_lib_tuple_element_t 201402L (C++14) std::tuple_element_t

#include <array>
#include <cstddef>
#include <iostream>
#include <ranges>
#include <tuple>
#include <type_traits>
#include <utility>
template<typename T1, typename T2, typename T3>
struct Triple
{
    T1 t1;
    T2 t2;
    T3 t3;
};
// プログラム定義型 Triple に対する std::tuple_element の特殊化:
template<std::size_t I, typename T1, typename T2, typename T3>
    struct std::tuple_element<I, Triple<T1, T2, T3>>
    { static_assert(false, "無効なインデックス"); }; 
template<typename T1, typename T2, typename T3>
    struct std::tuple_element<0, Triple<T1, T2, T3>> { using type = T1; };
template<typename T1, typename T2, typename T3>
    struct std::tuple_element<1, Triple<T1, T2, T3>> { using type = T2; };
template<typename T1, typename T2, typename T3>
    struct std::tuple_element<2, Triple<T1, T2, T3>> { using type = T3; };
template<typename... Args> struct TripleTypes
{
    static_assert(3 == sizeof...(Args), "正確に3つの型名が必要です");
    template<std::size_t N>
    using type = typename std::tuple_element_t<N, Triple<Args...>>;
};
int main()
{
    TripleTypes<char, int, float>::type<1> i{42};
    std::cout << i << '\n';
    using Tri = Triple<int, char, short>; //< プログラム定義型
    static_assert(std::is_same_v<std::tuple_element_t<0, Tri>, int> &&
                  std::is_same_v<std::tuple_element_t<1, Tri>, char> &&
                  std::is_same_v<std::tuple_element_t<2, Tri>, short>);
    using Tuple = std::tuple<int, char, short>;
    static_assert(std::is_same_v<std::tuple_element_t<0, Tuple>, int> &&
                  std::is_same_v<std::tuple_element_t<1, Tuple>, char> &&
                  std::is_same_v<std::tuple_element_t<2, Tuple>, short>);
    using Array3 = std::array<int, 3>;
    static_assert(std::is_same_v<std::tuple_element_t<0, Array3>, int> &&
                  std::is_same_v<std::tuple_element_t<1, Array3>, int> &&
                  std::is_same_v<std::tuple_element_t<2, Array3>, int>);
    using Pair = std::pair<Tuple, Tri>;
    static_assert(std::is_same_v<std::tuple_element_t<0, Pair>, Tuple> &&
                  std::is_same_v<std::tuple_element_t<1, Pair>, Tri>);
    using Sub = std::ranges::subrange<int*, int*>;
    static_assert(std::is_same_v<std::tuple_element_t<0, Sub>, int*> &&
                  std::is_same_v<std::tuple_element_t<1, Sub>, int*>);
}

出力:

42

欠陥報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 2212 C++11 cv修飾型に対する特殊化が一部ヘッダで要求されず、曖昧性が生じていた 要求される

関連項目

Structured binding (C++17) 指定された名前を初期化子の部分オブジェクトまたはタプル要素にバインドする
(C++11)
タプルライクな型の要素数を取得する
(クラステンプレート)
(C++11)
任意の数のタプルを連結して tuple を作成する
(関数テンプレート)