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
的顯式或部分特化,則程式非良構,無需診斷。
目錄 |
[編輯] 模板引數
Types... | - | tuple 儲存的元素型別。支援空列表。 |
[編輯] 成員函式
構造一個新的 tuple (公有成員函式) | |
將一個 tuple 的內容賦值給另一個(公有成員函式) | |
交換兩個 tuple 的內容(公有成員函式) |
[編輯] 非成員函式
(C++11) |
建立一個由引數型別定義的 tuple 物件(函式模板) |
(C++11) |
建立一個左值引用 tuple 或將 tuple 解包到各個物件中 (函式模板) |
(C++11) |
建立一個轉發引用的 tuple (函式模板) |
(C++11) |
透過連線任意數量的 tuple 建立一個 tuple (函式模板) |
(C++11) |
tuple 訪問指定的元素 (函式模板) |
(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20) |
按字典序比較 tuple 中的值 (函式模板) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
[編輯] 輔助概念
(C++23) |
指定型別實現了 tuple 協議 (std::get、std::tuple_element、std::tuple_size) (僅用於說明的概念*) |
[編輯] 輔助類
(C++11) |
獲取 tuple 的大小一個 |
獲取指定元素的型別 (類模板特化) | |
特化 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 特化允許在每個元素型別都支援的情況下,為列印 tuple
物件高效實現 std::print 和 std::println。
[編輯] 推導指南 (C++17 起)
[編輯] 註記
由於 tuple 的“形狀”——它的大小、元素型別以及這些型別的順序——是其型別簽名的一部分,因此它們必須在編譯時可用,並且只能依賴於其他編譯時資訊。這意味著對 tuple 的許多條件操作——特別是條件前置/追加和過濾——只有在條件可以在編譯時評估時才可能。例如,給定一個 std::tuple<int, double, int>,可以根據型別進行過濾——例如返回一個 std::tuple<int, int>——但不能根據每個元素是否為正數進行過濾(這將根據 tuple 的執行時值具有不同的型別簽名),除非所有元素本身都是 constexpr。
作為一種變通方法,可以使用 std::optional 的 tuple,但仍然無法根據執行時資訊調整大小。
在 N4387(作為 C++11 的缺陷報告應用)之前,函式不能使用複製列表初始化返回 tuple
std::tuple<int, int> foo_tuple() { return {1, -1}; // Error until N4387 return std::tuple<int, int>{1, -1}; // Always works return std::make_tuple(1, -1); // Always works }
[編輯] 示例
#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 structured binding: 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 Tuples [tuple]
- C++20 標準 (ISO/IEC 14882:2020)
- 20.5 Tuples [tuple]
- C++17 標準 (ISO/IEC 14882:2017)
- 23.5 Tuples [tuple]
- C++14 標準 (ISO/IEC 14882:2014)
- 20.4 Tuples [tuple]
- C++11 標準 (ISO/IEC 14882:2011)
- 20.4 Tuples [tuple]
[編輯] 另請參閱
實現二元組,即一對值 (類模板) |