定义于头文件 <tuple>
template< class... Types > | (C++11 起) |
类模板 std::tuple
是固定大小的异类值汇集。它是 std::pair 的推广。
若 (std::is_trivially_destructible_v<Types> && ...) 为 true ,则 | (C++17 起) |
模板形参
Types... | - | tuple 所存储的元素的类型。支持空列表。 |
构造函数
std::tuple<Types...>::tuple
constexpr tuple(); | (1) | (C++11 起) (条件性 explicit ) |
tuple( const Types&... args ); | (2) | (C++11 起) (C++14 起为 constexpr )(条件性 explicit ) |
template< class... UTypes > | (3) | (C++11 起) (C++14 起为 constexpr )(条件性 explicit ) |
template< class... UTypes > | (4) | (C++11 起) (C++14 起为 constexpr )(条件性 explicit ) |
template <class... UTypes> | (5) | (C++11 起) (C++14 起为 constexpr )(条件性 explicit ) |
template< class U1, class U2 > | (6) | (C++11 起) (C++14 起为 constexpr )(条件性 explicit ) |
template< class U1, class U2 > | (7) | (C++11 起) (C++14 起为 constexpr )(条件性 explicit ) |
tuple( const tuple& other ) = default; | (8) | (C++11 起) |
tuple( tuple&& other ) = default; | (9) | (C++11 起) |
template< class Alloc > | (10) | (C++11 起) (C++20 起为 constexpr )(条件性 explicit ) |
template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a, const Types&... args ); | (11) | (C++11 起) (C++20 起为 constexpr )(条件性 explicit ) |
template< class Alloc, class... UTypes > tuple( std::allocator_arg_t, const Alloc& a, UTypes&&... args ); | (12) | (C++11 起) (C++20 起为 constexpr )(条件性 explicit ) |
template <class Alloc, class... UTypes> tuple( std::allocator_arg_t, const Alloc& a, const tuple<UTypes...>& other ); | (13) | (C++11 起) (C++20 起为 constexpr )(条件性 explicit ) |
template< class Alloc, class... UTypes > tuple( std::allocator_arg_t, const Alloc& a, tuple<UTypes...>&& other ); | (14) | (C++11 起) (C++20 起为 constexpr )(条件性 explicit ) |
template< class Alloc, class U1, class U2 > tuple( std::allocator_arg_t, const Alloc& a, const pair<U1, U2>& p ); | (15) | (C++11 起) (C++20 起为 constexpr )(条件性 explicit ) |
template< class Alloc, class U1, class U2 > tuple( std::allocator_arg_t, const Alloc& a, pair<U1, U2>&& p ); | (16) | (C++11 起) (C++20 起为 constexpr )(条件性 explicit ) |
template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a, const tuple& other ); | (17) | (C++11 起) (C++20 起为 constexpr ) |
template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a, tuple&& other ); | (18) | (C++11 起) (C++20 起为 constexpr ) |
构造新的 tuple
。
1) 默认构造函数。值初始化所有元素。
此重载仅若 std::is_default_constructible<Ti>::value 对所有 i
为 true 才参与重载决议。
构造函数若且唯若对至少一个 i
有 Ti
不可从 {} 复制列表初始化才为 explicit 。
2) 直接构造函数。以对应参数初始化 tuple 的每个元素。
此重载仅若 sizeof...(Types) >= 1 与 std::is_copy_constructible<Ti>::value 对所有 i
为 true 才参与重载决议。
此构造函数若且唯若 std::is_convertible<const Ti&, Ti>::value 对至少一个 i
为 false 才为 explicit 。
3) 转换构造函数。以 std::forward<UTypes>(args) 中的对应值初始化 tuple 的每个元素。
此重载仅若 sizeof...(Types) == sizeof...(UTypes) 且 sizeof...(Types) >= 1 与 std::is_constructible<Ti, Ui&&>::value 对所有 i
为 true 才参与重载决议。
构造函数若且唯若才 std::is_convertible<Ui&&, Ti>::value 对至少一个 i 为 false 为 explicit 。
4) 转换复制构造函数。对 sizeof...(UTypes) 中所有 i
,以 std::get<i>(other) 初始化 tuple 的第 i 个元素。
此重载仅若
sizeof...(Types) == sizeof...(UTypes) 且
std::is_constructible_v<Ti, const Ui&> 对所有 i
为 true 且
sizeof...(Types) != 1 或
( Types...
展开成 T
且 UTypes...
展开成 U
时) std::is_convertible_v<const tuple<U>&, T> 、 std::is_constructible_v<T, const tuple<U>&> 与 std::is_same_v<T, U> 均为 false
才参与重载决议。
构造函数若且唯若 std::is_convertible<const Ui&, Ti>::value 对至少一个 i
为 false 才为 explicit 。
5) 转换移动构造函数。对 sizeof...(UTypes) 中所有 i
,以 std::forward<Ui>(std::get<i>(other)) 初始化 tuple 的第 i 个元素。
此重载仅若
sizeof...(Types) == sizeof...(UTypes) 且
std::is_constructible_v<Ti, Ui&&> 对所有 i
为 true 且
sizeof...(Types) != 1 或
( Types...
展开成 T
且 UTypes...
展开成 U
时) std::is_convertible_v<tuple<U>, T> 、 std::is_constructible_v<T, tuple<U>> 与 std::is_same_v<T, U> 均为 false
才参与重载决议。
构造函数若且唯若 std::is_convertible<Ui&&, Ti>::value 对至少一个 i
为 false 才为 explicit 。
6) pair 复制构造函数。构造 2-tuple ,从 p.first
构造第一个元素,从 p.second
构造第二个元素。
此重载仅若 sizeof...(Types) == 2 与 std::is_constructible<T0,const U1&>::value 与 std::is_constructible<T1, const U2&>::value 均为 true 才参与重载决议。
构造函数若且唯若 std::is_convertible<const U1&, T0>::value 或 std::is_convertible<const U2&, T1>::value 为 false 才为 explicit 。 }}
7) pair 移动构造函数。构造 2-tuple ,从 std::forward<U1>(p.first) 构造第一个元素,从 std::forward<U2>(p.second) 构造第二个元素。
此重载仅若 sizeof...(Types) == 2 与 std::is_constructible<T0, U1&&>::value 与 std::is_constructible<T1, U2&&>::value 均为 true 才参与重载决议。
构造函数若且唯若 std::is_convertible<U1&&, T0>::value 或 std::convertible<U2&&, T1>::value 为 false 才为 explicit 。
8) 隐式定义的复制构造函数。以 other
的对应元素初始化 tuple 的每个元素。
若此函数进行的每个操作都是 constexpr ,则它是 constexpr 。对于空 tuple std::tuple<> ,它是 constexpr 。
要求 std::is_copy_constructible<Ti>::value 对所有 i
为 true 。
9) 隐式定义的移动构造函数。以 std::forward<Ui>(std::get<i>(other)) 构造 tuple 的第 i 个元素。
若此函数进行的每个操作都是 constexpr ,则它是 constexpr 。对于空 tuple std::tuple<> ,它是 constexpr 。
要求 std::is_move_constructible<Ti>::value 对所有 i
为 true 。
10-18) 等同于 (1-9) ,除了以使用分配器构造创建每个元素每个元素,即以分配器 (Allocator) 对象 a
为额外参数传递给每个 std::uses_allocator<Ui, Alloc>::value 为 true 的对象的构造函数。
参数
args | - | 用于初始化 tuple 每个元素的值 |
other | - | 用于初始化 tuple 每个元素的值的 tuple |
p | - | 用于初始化此 2-tuple 的两个元素的值的 pair |
a | - | 用于使用分配器构造的分配器 |
注意
条件性 explicit 的构造函数使得可以用列表初始化语法于复制初始化语境构造 tuple :
std::tuple<int, int> foo_tuple()
{
return {1, -1}; // N4387 前错误
return std::make_tuple(1, -1); // 始终工作
}
注意若列表中某元素不可隐式转换成目标 tuple 中的对应元素,则构造函数变为 explicit 。
using namespace std::chrono;
void launch_rocket_at(std::tuple<hours, minutes, seconds>);
launch_rocket_at({hours(1), minutes(2), seconds(3)}); // OK
launch_rocket_at({1, 2, 3}); // 错误: int 不可隐式转换成 duration
launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // OK
调用示例
#include <tuple>
#include <iostream>
#include <string>
#include <typeinfo>
#include <stdexcept>
#include <iostream>
#include <vector>
#include <memory>
// 打印任何大小 tuple 的辅助函数
template<class Tuple, std::size_t N>
struct TuplePrinter
{
static void print(const Tuple& t)
{
TuplePrinter < Tuple, N - 1 >::print(t);
std::cout << ", " << std::get < N - 1 > (t);
}
};
template<class Tuple>
struct TuplePrinter<Tuple, 1>
{
static void print(const Tuple& t)
{
std::cout << std::get<0>(t);
}
};
template<class... Args>
void print(const std::tuple<Args...>& t)
{
std::cout << "(";
TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
std::cout << ")" << std::endl;
}
// 辅助函数结束
int main()
{
//1) 默认构造函数。值初始化所有元素。
std::tuple<int, std::string, double> tuple1;
std::cout << "Value-initialized: ";
print(tuple1);
//2) 直接构造函数。以对应参数初始化 tuple 的每个元素。
std::tuple<int, std::string, double> tuple2(42, "Test", -3.14);
std::cout << "Initialized with values: ";
print(tuple2);
//3) 转换构造函数。以 std::forward<UTypes>(args) 中的对应值初始化 tuple 的每个元素。
std::tuple<char, std::string, int> tuple3(std::move(tuple2));
std::cout << "Implicitly converted: ";
print(tuple3);
//4) 转换复制构造函数。对 sizeof...(UTypes) 中所有 i ,以 std::get<i>(other) 初始化 tuple 的第 i 个元素。
std::tuple<char, std::string, int> tuple4(tuple2);
std::cout << "Implicitly converted: ";
print(tuple4);
//5) 转换移动构造函数。对 sizeof...(UTypes) 中所有 i ,
//以 std::forward<Ui>(std::get<i>(other)) 初始化 tuple 的第 i 个元素。
std::tuple<char, std::string, int> tuple5(std::move(tuple2));
std::cout << "Implicitly converted: ";
print(tuple5);
//6) pair 复制构造函数。构造 2-tuple ,从 p.first 构造第一个元素,从 p.second 构造第二个元素。
std::tuple<int, double> tuple6(std::make_pair(42, 3.14));
std::cout << "Constructed from a pair";
print(tuple6);
//7) pair 移动构造函数。构造 2-tuple ,从 std::forward<U1>(p.first) 构造第一个元素,
//从 std::forward<U2>(p.second) 构造第二个元素。
std::pair<int, double> pair1 = std::make_pair(42, 3.14);
std::tuple<int, double> tuple7(std::move(pair1));
std::cout << "Constructed from a pair";
print(tuple7);
//8) 隐式定义的复制构造函数。以 other 的对应元素初始化 tuple 的每个元素。
std::tuple<char, std::string, int> tuple8(tuple2);
std::cout << "Implicitly converted: ";
print(tuple8);
//9) 隐式定义的移动构造函数。以 std::forward<Ui>(std::get<i>(other)) 构造 tuple 的第 i 个元素。
std::tuple<char, std::string, int> tuple9(std::move(tuple2));
std::cout << "Implicitly converted: ";
print(tuple9);
return 0;
}
输出
Value-initialized: (0, , 0)
Initialized with values: (42, Test, -3.14)
Implicitly converted: (*, Test, -3)
Implicitly converted: (*, , -3)
Implicitly converted: (*, , -3)
Constructed from a pair(42, 3.14)
Constructed from a pair(42, 3.14)
Implicitly converted: (*, , -3)
Implicitly converted: (*, , -3)