std:: tuple
|
定义于头文件
<tuple>
|
||
|
template
<
class
...
Types
>
class tuple ; |
(C++11 起) | |
类模板
std::tuple
是一个固定大小的异构值集合。它是
std::pair
的泛化形式。
如果对于
Types
中的每个
Ti
,
std::
is_trivially_destructible
<
Ti
>
::
value
均为
true
,则
std::tuple
的析构函数是平凡析构函数。
如果程序声明了
std::tuple
的
显式
或
部分
特化,则该程序是非良构的,不要求诊断。
目录 |
模板参数
| 类型... | - | 元组存储的元素类型。支持空列表。 |
成员函数
构造新的
tuple
(公开成员函数) |
|
将一个
tuple
的内容赋给另一个
(公开成员函数) |
|
交换两个
tuple
的内容
(公开成员函数) |
非成员函数
|
(C++11)
|
创建由参数类型定义的
tuple
对象
(函数模板) |
|
(C++11)
|
创建左值引用组成的
tuple
或将 tuple 解包为独立对象
(函数模板) |
|
(C++11)
|
创建由
转发引用
组成的
tuple
(函数模板) |
|
(C++11)
|
通过连接任意数量的 tuple 来创建
tuple
(函数模板) |
|
(C++11)
|
访问 tuple 的指定元素
(函数模板) |
|
(removed in C++20)
(removed in C++20)
(removed in C++20)
(removed in C++20)
(removed in C++20)
(C++20)
|
按字典序比较 tuple 中的值
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
辅助概念
|
(C++23)
|
指定类型实现了
元组协议
( std::get , std::tuple_element , std::tuple_size ) ( 仅用于说明的概念* ) |
辅助类
|
(C++11)
|
获取
|
|
(C++11)
|
获取指定元素的类型
(类模板特化) |
|
(C++11)
|
特化
std::uses_allocator
类型特征
(类模板特化) |
确定
tuple
与
tuple-like
类型的公共引用类型
(类模板特化) |
|
|
(C++23)
|
确定
tuple
与
tuple-like
类型的公共类型
(类模板特化) |
|
(C++23)
|
为
tuple
提供格式化支持
(类模板特化) |
|
(C++11)
|
在使用
tie
解包
tuple
时跳过元素的占位符
(常量) |
辅助特化
|
template
<
class
...
Ts
>
constexpr
bool
enable_nonlocking_formatter_optimization
<
std
::
tuple
<
Ts...
>>
|
(C++23 起) | |
此
std::enable_nonlocking_formatter_optimization
的特化使得当每个元素类型均启用该优化时,能够高效实现
std::print
和
std::println
对
tuple
对象的格式化输出。
推导指引 (C++17 起)
注释
由于元组的“形态”——其大小、元素类型及类型顺序——都属于其类型签名的一部分,这些特性必须在编译期确定,且仅能依赖于其他编译期信息。这意味着对元组的许多条件操作——特别是条件性前置/追加和过滤——仅当条件可在编译期求值时才能实现。例如,给定一个 std :: tuple < int , double , int > ,可以基于类型进行过滤——例如返回 std :: tuple < int , int > ——但无法基于元素是否为正数进行过滤(这会因元组在运行时的取值不同而产生不同的类型签名),除非所有元素本身都是 constexpr 。
作为一种变通方案,可以使用由 std:: optional 组成的元组,但仍然无法根据运行时信息调整其大小。
在 N4387 (作为 C++11 的缺陷报告应用)之前,函数无法通过复制列表初始化返回元组:
std::tuple<int, int> foo_tuple() { return {1, -1}; // 在 N4387 标准前会报错 return std::tuple<int, int>{1, -1}; // 始终有效 return std::make_tuple(1, -1); // 始终有效 }
示例
#include <iostream> #include <stdexcept> #include <string> #include <tuple> std::tuple<double, char, std::string> get_student(int id) { switch (id) { case 0: return {3.8, 'A', "Lisa Simpson"}; case 1: return {2.9, 'C', "Milhouse Van Houten"}; case 2: return {1.7, 'D', "Ralph Wiggum"}; case 3: return {0.6, 'F', "Bart Simpson"}; } throw std::invalid_argument("id"); } int main() { const auto student0 = get_student(0); std::cout << "ID: 0, " << "GPA: " << std::get<0>(student0) << ", " << "grade: " << std::get<1>(student0) << ", " << "name: " << std::get<2>(student0) << '\n'; const auto student1 = get_student(1); std::cout << "ID: 1, " << "GPA: " << std::get<double>(student1) << ", " << "grade: " << std::get<char>(student1) << ", " << "name: " << std::get<std::string>(student1) << '\n'; double gpa2; char grade2; std::string name2; std::tie(gpa2, grade2, name2) = get_student(2); std::cout << "ID: 2, " << "GPA: " << gpa2 << ", " << "grade: " << grade2 << ", " << "name: " << name2 << '\n'; // C++17 结构化绑定: const auto [gpa3, grade3, name3] = get_student(3); std::cout << "ID: 3, " << "GPA: " << gpa3 << ", " << "grade: " << grade3 << ", " << "name: " << name3 << '\n'; }
输出:
ID: 0, GPA: 3.8, grade: A, name: Lisa Simpson ID: 1, GPA: 2.9, grade: C, name: Milhouse Van Houten ID: 2, GPA: 1.7, grade: D, name: Ralph Wiggum ID: 3, GPA: 0.6, grade: F, name: Bart Simpson
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 应用于 | 发布时行为 | 正确行为 |
|---|---|---|---|
| LWG 2796 | C++11 |
std::tuple
的析构函数平凡性未作规定
|
已作规定 |
| LWG 3990 | C++11 |
程序可以声明
std::tuple
的显式或
部分特化 |
此情况下程序非良构
(不要求诊断) |
参考文献
- C++23 标准 (ISO/IEC 14882:2024):
-
- 22.4 元组 [tuple]
- C++20 标准 (ISO/IEC 14882:2020):
-
- 20.5 元组 [tuple]
- C++17 标准 (ISO/IEC 14882:2017):
-
- 23.5 元组 [tuple]
- C++14 标准 (ISO/IEC 14882:2014):
-
- 20.4 元组 [tuple]
- C++11 标准 (ISO/IEC 14882:2011):
-
- 20.4 元组 [tuple]
参见
|
实现二元组,即一对值的容器
(类模板) |