Namespaces
Variants

std::tuple<Types...>::tuple

ja.cppreference.net より
 
 
ユーティリティライブラリ
言語サポート
型サポート (基本型、RTTI)
ライブラリ機能テストマクロ (C++20)
プログラムユーティリティ
可変個引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

汎用ユーティリティ
関係演算子 (C++20で非推奨)
整数比較関数
(C++20)(C++20)(C++20)    
(C++20)
swap と 型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
共通ボキャブラリ型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
 
ヘッダ <tuple>
constexpr tuple();
で定義 (1) (C++11以上)
(条件付きでexplicit)
tuple( const Types&... args );
(2) (C++11以上)
(C++14以上でconstexpr)
(条件付きでexplicit)
template< class... UTypes >
tuple( UTypes&&... args );
(3) (C++11以上)
(C++14以上でconstexpr)
(条件付きでexplicit)
template< class... UTypes >
constexpr tuple( tuple<UTypes...>& other );
(4) (C++23以上)
(条件付きでexplicit)
template< class... UTypes >
tuple( const tuple<UTypes...>& other );
(5) (C++11以上)
(C++14以上でconstexpr)
(条件付きでexplicit)
template< class... UTypes >
tuple( tuple<UTypes...>&& other );
(6) (C++11以上)
(C++14以上でconstexpr)
(条件付きでexplicit)
template< class... UTypes >
constexpr tuple( const tuple<UTypes...>&& other );
(7) (C++23以上)
(条件付きでexplicit)
template< class U1, class U2 >
constexpr tuple( std::pair<U1, U2>& p );
(8) (C++23以上)
(条件付きでexplicit)
template< class U1, class U2 >
tuple( const std::pair<U1, U2>& p );
(9) (C++11以上)
(C++14以上でconstexpr)
(条件付きでexplicit)
template< class U1, class U2 >
tuple( std::pair<U1, U2>&& p );
(10) (C++11以上)
(C++14以上でconstexpr)
(条件付きでexplicit)
template< class U1, class U2 >
constexpr tuple( const std::pair<U1, U2>&& p );
(11) (C++23以上)
(条件付きでexplicit)
template< tuple-like UTuple >
constexpr tuple( UTuple&& u );
(12) (C++23以上)
(条件付きでexplicit)
tuple( const tuple& other ) = default;
(13) (C++11以上)
tuple( tuple&& other ) = default;
(14) (C++11以上)
アロケータ拡張コンストラクタ
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a );
(15) (C++11以上)
(C++20以上でconstexpr)
(条件付きでexplicit)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a,
       const Types&... args );
(16) (C++11以上)
(C++20以上でconstexpr)
(条件付きでexplicit)
template< class Alloc, class... UTypes >
tuple( std::allocator_arg_t, const Alloc& a,
       UTypes&&... args );
(17) (C++11以上)
(C++20以上でconstexpr)
(条件付きでexplicit)
template< class Alloc, class... UTypes >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
                 tuple<UTypes...>& other );
(18) (C++23以上)
(条件付きでexplicit)
template< class Alloc, class... UTypes >
tuple( std::allocator_arg_t, const Alloc& a,
       const tuple<UTypes...>& other );
(19) (C++11以上)
(C++20以上でconstexpr)
(条件付きでexplicit)
template< class Alloc, class... UTypes >
tuple( std::allocator_arg_t, const Alloc& a,
       tuple<UTypes...>&& other );
(20) (C++11以上)
(C++20以上でconstexpr)
(条件付きでexplicit)
template< class Alloc, class... UTypes >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
                 const tuple<UTypes...>&& other );
(21) (C++23以上)
(条件付きでexplicit)
template< class Alloc, class U1, class U2 >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
                 std::pair<U1, U2>& p );
(22) (C++23以上)
(条件付きでexplicit)
template< class Alloc, class U1, class U2 >
tuple( std::allocator_arg_t, const Alloc& a,
       const std::pair<U1, U2>& p );
(23) (C++11以上)
(C++20以上でconstexpr)
(条件付きでexplicit)
template< class Alloc, class U1, class U2 >
tuple( std::allocator_arg_t, const Alloc& a,
       std::pair<U1, U2>&& p );
(24) (C++11以上)
(C++20以上でconstexpr)
(条件付きでexplicit)
template< class Alloc, class U1, class U2 >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
                 const std::pair<U1, U2>&& p );
(25) (C++23以上)
(条件付きでexplicit)
template< class Alloc, tuple-like UTuple >
constexpr tuple( std::allocator_arg_t, const Alloc& a, UTuple&& u );
(26) (C++23以上)
(条件付きでexplicit)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a,
       const tuple& other );
(27) (C++11以上)
(C++20以上でconstexpr)
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a,
       tuple&& other );
(28) (C++11以上)
(C++20以上でconstexpr)

新しいtupleを構築します。

以下の説明では、

  • i は範囲 [0, sizeof...(Types)) 内の順序であり、
  • Ti は i 内の Types 番目の型であり、
  • Ui は i という名前のテンプレートパラメータパック内の UTypes 番目の型であり、

インデックスは0から始まります。

1) デフォルトコンストラクタ。 すべての要素を値初期化します。 デフォルトコンストラクタは、sizeof...(Types) == 0 の場合にトリビアルです。
  • このオーバーロードは、すべての std::is_default_constructible<Ti>::value に対して true が i である場合にのみオーバーロード解決に参加します。
  • このコンストラクタは、少なくとも1つの explicit に対して Ti が {} からコピーリスト初期化可能でない場合に限り i です。
2) 直接コンストラクタ。 対応するパラメータでtupleの各要素を初期化します。
  • このオーバーロードは、sizeof...(Types) >= 1 かつ すべての std::is_copy_constructible<Ti>::value に対して true が i である場合にのみオーバーロード解決に参加します。
  • このコンストラクタは、少なくとも1つの explicit に対して std::is_convertible<const Ti&, Ti>::value が false である場合に限り i です。
3) 変換コンストラクタ。 対応する std::forward<UTypes>(args) の値でtupleの各要素を初期化します。
  • このオーバーロードは、以下の場合にのみオーバーロード解決に参加します:
    • sizeof...(Types) == sizeof...(UTypes)
    • sizeof...(Types) >= 1
    • std::is_constructible<Ti, Ui>::value が すべての true に対して i であり、かつ
    • D を std::decay<U0>::type(C++20まで)std::remove_cvref_t<U0>(C++20以上) とするとき、
      • sizeof...(Types) == 1 の場合、D は std::tuple ではない。 そうでなければ、
      • sizeof...(Types) == 2 または sizeof...(Types) == 3 の場合、D は std::allocator_arg_t ではない、または T0 は std::allocator_arg_t である。
  • このコンストラクタは、少なくとも1つの explicit に対して std::is_convertible<Ui, Ti>::value が false である場合に限り i です。
(C++23以上)
4-7) 変換コンストラクタ。 other の対応する要素でtupleの各要素を初期化します。

形式的には、FWD(other) を std::forward<decltype(other)>(other) とし、すべての i について、tupleの i 番目の要素を std::get<i>(FWD(other)) で初期化します。

  • このオーバーロードは、以下の場合にのみオーバーロード解決に参加します:
    • sizeof...(Types) == sizeof...(UTypes)
    • std::is_constructible_v<Ti, decltype(std::get<i>(FWD(other)))> が すべての true に対して i であり、かつ
    • 以下のいずれか:
      • sizeof...(Types) が 1 ではない、または
      • (Types... が T に展開され、UTypes... が U に展開される場合) std::is_convertible_v<decltype(other), T>, std::is_constructible_v<T, decltype(other)>, std::is_same_v<T, U> のすべてが false である。
  • これらのコンストラクタは、少なくとも1つの explicit に対して std::is_convertible_v<decltype(std::get<i>(FWD(other))), Ti> が false である場合に限り i です。
  • 参照である要素の初期化が一時オブジェクトに束縛することになる場合、これらのコンストラクタは削除されたものとして定義されます。
(C++23以上)
8-11) ペアコンストラクタ。 p の対応する要素から構築された各要素で2要素のtupleを構築します。

形式的には、FWD(p) を std::forward<decltype(p)>(p) とし、最初の要素を std::get<0>(FWD(p)) で、2番目の要素を std::get<1>(FWD(p)) で初期化します。

  • このオーバーロードは、以下の場合にのみオーバーロード解決に参加します:
    • sizeof...(Types) == 2
    • std::is_constructible_v<T0, decltype(std::get<0>(FWD(p)))> が true であり、かつ
    • std::is_constructible_v<T1, decltype(std::get<1>(FWD(p)))> が true である。
  • このコンストラクタは、explicit または std::is_convertible_v<decltype(std::get<0>(FWD(p))), T0> が std::is_convertible_v<decltype(std::get<1>(FWD(p))), T1> である場合に限り false です。
  • 参照である要素の初期化が一時オブジェクトに束縛することになる場合、これらのコンストラクタは削除されたものとして定義されます。
(C++23以上)
12) tuple-like コンストラクタ。 u の対応する要素から構築された各要素でtupleを構築します。

形式的には、すべての i について、tupleの i 番目の要素を std::get<i>(std::forward<UTuple>(u)) で初期化します。

  • このオーバーロードは、以下の場合にのみオーバーロード解決に参加します:
    • std::same_as<std::remove_cvref_t<UTuple>, std::tuple> が false であり、
    • std::remove_cvref_t<UTuple> が std::ranges::subrange の特殊化ではなく、
    • sizeof...(Types) が std::tuple_size_v<std::remove_cvref_t<UTuple>> と等しく、すべての
    • std::is_constructible_v<Ti, decltype(std::get<i>(std::forward<UTuple>(u)))> に対して true が i であり、かつ
    • 以下のいずれか:
      • sizeof...(Types) が 1 ではない、または
      • (Types... が T に展開される場合) std::is_convertible_v<UTuple, T> と std::is_constructible_v<T, UTuple> の両方が false である。
  • 参照である要素の初期化が一時オブジェクトに束縛することになる場合、このコンストラクタは削除されたものとして定義されます。
13) 暗黙に定義されるコピーコンストラクタ。 other の対応する要素でtupleの各要素を初期化します。
  • このコンストラクタは、実行するすべての操作がconstexprである場合にconstexprです。 空のtuple std::tuple<> の場合はconstexprです。
  • std::is_copy_constructible<Ti>::value は すべての true に対して i でなければならず、そうでなければ 動作は未定義です(C++20まで)プログラムは ill-formed です(C++20以上)。
14) 暗黙に定義されるムーブコンストラクタ。 すべての i について、tupleの i 番目の要素を std::forward<Ui>(std::get<i>(other)) で初期化します。
  • このコンストラクタは、実行するすべての操作がconstexprである場合にconstexprです。 空のtuple std::tuple<> の場合はconstexprです。
  • std::is_move_constructible<Ti>::value は すべての true に対して i でなければならず、そうでなければ 動作は未定義です(C++20まで)このオーバーロードはオーバーロード解決に参加しません(C++20以上)。
15-28) (1-14) と同一ですが、各要素は uses-allocator 構文 によって作成される点が異なります。つまり、a が std::uses_allocator<Ui, Alloc>::value である各要素のコンストラクタに、アロケータオブジェクト true が追加の引数として渡されます。

パラメータ

args - タプルの各要素を初期化するために使用される値
other - タプルの各要素を初期化するために使用される値のタプル
p - 2要素タプルの両方の要素を初期化するために使用される値のペア
u - タプルの各要素を初期化するために使用される値の tuple-like オブジェクト
a - アロケータ構築で使用するアロケータ

注記

条件付き明示的コンストラクタは、リスト初期化構文を使用してコピー初期化コンテキストでタプルを構築することを可能にします:

std::tuple<int, int> foo_tuple() 
{
    // return {1, -1};             // N4387以前ではエラー
    return std::make_tuple(1, -1); // 常に動作する
}

リストの一部の要素が対象のタプルの対応する要素に暗黙的に変換できない場合、コンストラクタは明示的になることに注意してください:

using namespace std::chrono;
void launch_rocket_at(std::tuple<hours, minutes, seconds>);
launch_rocket_at({hours(1), minutes(2), seconds(3)}); // 正常
launch_rocket_at({1, 2, 3}); // エラー: intはdurationに暗黙的に変換できません
launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // 正常

例

#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <vector>
// ベクターをストリームに出力するヘルパー関数
template<class Os, class T>
Os& operator<<(Os& os, std::vector<T> const& v)
{
    os << '{';
    for (auto i{v.size()}; const T& e : v)
        os << e << (--i ? "," : "");
    return os << '}';
}
template<class T>
void print_single(T const& v)
{
    if constexpr (std::is_same_v<T, std::decay_t<std::string>>)
        std::cout << std::quoted

(注:指示に従い、HTMLタグ・属性は翻訳せず、C++固有用語も翻訳していません。表示されるテキスト「std::quoted」はC++標準ライブラリの関数名であるため、そのまま保持しています)(v);
    else if constexpr (std::is_same_v<std::decay_t<T>, char>)
        std::cout << "'" << v << "'";
    else
        std::cout << v;
}
// 任意サイズのタプルを出力するためのヘルパー関数
template<class Tuple, std::size_t N>
struct TuplePrinter
{
    static void print(const Tuple& t)
    {
        TuplePrinter<Tuple, N - 1>::print(t);
        std::cout << ", ";
        print_single(std::get<N - 1>(t));
    }
};
template<class Tuple>
struct TuplePrinter<Tuple, 1>
{
    static void print(const Tuple& t)
    {
        print_single(std::get<0>(t));
    }
};
template<class... Args>
void print(std::string_view message, const std::tuple<Args...>& t)
{
    std::cout << message << " (";
    TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
    std::cout << ")\n";
}
// ヘルパー関数の終了
int main()
{
    std::tuple<int, std::string, double> t1;
    print("値初期化済み、t1:", t1);
    std::tuple<int, std::string, double> t2{42, "テスト", -3.14};
    print("値で初期化、t2:", t2);
    std::tuple<char, std::string, int> t3{t2};
    print("暗黙的に変換されました、t3:", t3);
    std::tuple<int, double> t4{std::make_pair(42, 3.14)};
    print("ペアから構築、t4:", t4);
    // 単一引数コンストラクタを持つ Allocator my_alloc が与えられた場合
    // my_alloc(int); my_alloc(1) を使用してベクター内に5つのintを割り当てる
    using my_alloc = std::allocator<int>;
    std::vector<int, my_alloc> v{5, 1, my_alloc{/* 1 */}};
    // my_alloc(2)を使用してタプル内のベクターで5つのintを割り当てる
    std::tuple<int, std::vector<int, my_alloc>, double> t5
        {std::allocator_arg, my_alloc{/* 2 */}, 42, v, -3.14};
    print("アロケータで構築されました、t5:", t5);
}

出力例:

値初期化済み, t1: (0, "", 0)
値で初期化済み, t2: (42, "Test", -3.14)
暗黙的に変換済み, t3: ('*', "Test", -3)
ペアから構築済み, t4: (42, 3.14)
アロケータで構築済み, t5: (42, {1,1,1,1,1}, -3.14)

欠陥報告

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

DR 適用バージョン 公開時の動作 修正後の動作
LWG 2510 C++11 デフォルトコンストラクタが暗黙的であった 条件付き明示的(conditionally-explicit)に変更
LWG 3121 C++11 1要素タプルのコンストラクタが制約を再帰的にチェックする可能性あり;
allocator_arg_t 引数による曖昧性が生じる
コンストラクタをさらに制約
付与
LWG 3158 C++11 デフォルトコンストラクタに対応する
アロケータ使用コンストラクタが暗黙的であった
条件付き明示的(conditionally-explicit)に変更
LWG 3211 C++11 tuple<> のデフォルトコンストラクタが
トリビアルかどうかが未規定であった
トリビアルであることを要求
LWG 4045 C++23 tuple-like コンストラクタがダングリング参照を
作成する可能性がある
削除定義(deleted)に変更
N4387 C++11 一部のコンストラクタが明示的であり、有用な動作を妨げていた ほとんどのコンストラクタを
条件付き明示的(conditionally-explicit)に変更

関連項目

あるtupleの内容を別のtupleに代入する
(public member function)
(C++11)
引数の型によって定義される型のtupleオブジェクトを作成する
(function template)
(C++11)
左辺値参照のtupleを作成する、またはtupleを個々のオブジェクトに展開する
(function template)
転送参照 のtupleを作成する
(function template)
新しいpairを構築する
(std::pair<T1,T2>のpublic member function)