std::tuple<Types...>::tuple
ja.cppreference.net より
| ヘッダ <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) >= 1std::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) == 2std::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) |
|
(C++11)
|
転送参照
のtupleを作成する
(function template) |
新しいpairを構築する
( std::pair<T1,T2>のpublic member function)
|