当前位置: 首页 > news >正文

【C++ 11 模板类】tuple 元组

文章目录

  • 【 1. 基础概念 】
    • 与 `pair` 和 `struct` 的对比
  • 【 2. tuple 的创建 】
    • 2.1 构造函数的方式创建
    • 2.2 使用花括号初始化
    • 2.3 使用 `std::make_tuple`
    • 2.4 使用 `std::tie`(用于解包,但也可用于初始化空 tuple)
    • 2.5 `empty_tuple` 创建空 tuple
    • 2.6 从 tuple 创建另一个 tuple(类型转换)
  • 【 3. 访问 tuple 元素 】
    • 3.1 使用 `std::get<index>(tuple)`
    • 3.2 结构化绑定(C++17,强烈推荐)
  • 【 4. tuple 的操作 】
    • 4.1 获取 tuple 大小 `tuple_size_v<decltype(t)>`
    • 4.2 获取特定位置的类型
    • 4.3 比较操作
    • 4.4 拼接 tuple `std::tuple_cat`
    • 4.5 遍历 tuple
  • 【 5. 应用场景 】
    • 5.1 函数返回多个值
    • 5.2 作为容器的键

【 1. 基础概念 】

std::tuple 在 C++11 引入,用于将不同类型的数据组合成一个单一的对象。它类似于 std::pair,但可以包含任意数量的元素(包括零个)。

  • 定义std::tuple 是一个模板类,可以存储固定数量的、不同类型的数据元素。
  • 头文件#include <tuple>
  • 命名空间std
  • 编译时确定大小:tuple 的大小(即包含的元素个数)在编译时就已经完全确定,并且不可改变。它不是动态容器。

pairstruct 的对比

特性std::tuplestd::pairstruct
元素数量任意2任意
元素命名无(通过索引)first, second自定义
可读性
灵活性
适用场景临时组合、泛型键值对有明确语义的数据

【 2. tuple 的创建 】

2.1 构造函数的方式创建

tuple<int, string, double> t1(10, "Zhen", 95.5);

2.2 使用花括号初始化

tuple<int, string> t2{42, "Sheng"};
tuple<int, string> t3 = {42, "Wo"};
tuple<int, double> t4{}; // 所有成员被默认初始化
tuple<int, double> t5 = {}; // 所有成员被默认初始化

2.3 使用 std::make_tuple

auto t4 = make_tuple(20, "Ai", 88.0);
// 类型自动推导,推荐使用

2.4 使用 std::tie(用于解包,但也可用于初始化空 tuple)

int a; 
string b ;
double c;
auto t3 = tie(a, b, c); // 创建引用 tuple

2.5 empty_tuple 创建空 tuple

tuple<> empty_tuple;

2.6 从 tuple 创建另一个 tuple(类型转换)

auto t1 = make_tuple(1, 2.5);
auto t2 = make_tuple<long, float>(t1); // 类型转换

【 3. 访问 tuple 元素 】

3.1 使用 std::get<index>(tuple)

  • 通过索引访问元素(索引从 0 开始)
#include <iostream>
#include <tuple>
#include <string>
using namespace std;
int main() {tuple <int,float,string>(1314, 0.521, "Ni");// 通过索引访问元素(索引从 0 开始)cout << "Index 0: " << get<0>(t) << "\n";cout << "Index 1: " << get<1>(t) << "\n";cout << "Index 2: " << get<2>(t) << "\n";return 0;
}
  • 注意索引 inde 必须是编译时常量,不能是变量
#include <iostream>
#include <tuple>
#include <string>
using namespace std;
int main() {tuple <int,float,string> t(1314, 0.521, "Ni");int index = 0;// 报错:get<>() 的 <> 中必须是常量cout << "Index 0: " << get<index>(t) << "\n";//正确cout << "Index 0: " << get<0>(t) << "\n";return 0;
}
  • std::get 也可以用于修改元素:
tuple <int,float,string> t(1314, 0.521, "Ni");
get<2>(t) = "new";

3.2 结构化绑定(C++17,强烈推荐)

  • 这是访问 tuple 最优雅的方式:
#include <iostream>
#include <tuple>
#include <string>
using namespace std;
int main() {auto t = make_tuple(42, 3.14, string("Modern C++"));// 结构化绑定:将 tuple 解包为独立变量auto [id, value, name] = t; // 这行代码的含义是:“把这个 tuple 类型的变量 t 的第一个元素绑定到名为 id 的变量,第二个绑定到 value,第三个绑定到 name。”cout << "ID: " << id << ", Value: " << value << ", Name: " << name << "\n";// 也可以声明为引用以修改原 tupleauto& [ref_id, ref_value, ref_name] = t;ref_id = 99;cout << "Modified ID: " << get<0>(t) << "\n"; // 99return 0;
}

【 4. tuple 的操作 】

4.1 获取 tuple 大小 tuple_size_v<decltype(t)>

tuple_size_v<decltype(t)>

auto t = std::make_tuple(1, 2.5, "hello", true);
constexpr size_t size = tuple_size_v<decltype(t)>; // C++17// 输出为 3

4.2 获取特定位置的类型

auto t = std::make_tuple(1, 2.5, "hello", true);
using ThirdType = tuple_element_t<2, decltype(t)>;
// ThirdType 是 std::string

4.3 比较操作

  • tuple 支持完整的比较操作(==, !=, <, <=, >, >=),按字典序比较:
  • tuple 内的元素依次比较,直到比较出结果
#include <iostream>
#include <tuple>
#include <string>
using namespace std;
int main() {auto t1 = make_tuple(1, "apple");auto t2 = make_tuple(1, "banana");auto t3 = make_tuple(2, "apple");cout << (t1 < t2) << "\n";  // 1cout << (t1 < t3) << "\n";  // 1cout << (t2 < t3) << "\n";  // 1return 0;
}

4.4 拼接 tuple std::tuple_cat

#include <iostream>
#include <tuple>
#include <string>
using namespace std;
int main() {auto t1 = make_tuple(1, 2);auto t2 = make_tuple(3.14, "pi");auto t3 = make_tuple(true);// 拼接多个 tupleauto combined = tuple_cat(t1, t2, t3);// combined 类型: tuple<int, int, double, const char*, bool>cout << "Combined size: " << tuple_size_v<decltype(combined)> << "\n";return 0;
}

4.5 遍历 tuple

// C++17 示例:打印 tuple 所有元素
template<typename Tuple, std::size_t... I>
void print_tuple_impl(const Tuple& t, std::index_sequence<I...>) {((std::cout << (I == 0 ? "" : ", ") << std::get<I>(t)), ...);std::cout << "\n";
}template<typename... Args>
void print_tuple(const std::tuple<Args...>& t) {print_tuple_impl(t, std::index_sequence_for<Args...>{});
}// 使用
auto t = std::make_tuple(1, 2.5, "hello");
print_tuple(t); // 输出: 1, 2.5, hello

【 5. 应用场景 】

5.1 函数返回多个值

#include <tuple>
#include <iostream>
using namespace  std;tuple<int, int, double> divide_with_remainder(int a, int b) {return make_tuple(a / b, a % b, static_cast<double>(a) / b);
}int main() {auto [quotient, remainder, decimal] = divide_with_remainder(10, 3);cout << "Quotient: " << quotient << ", Remainder: " << remainder << ", Decimal: " << decimal << "\n";return 0;
}

5.2 作为容器的键

map<tuple<int, string>, double> student_grades;
student_grades[{1, "Math"}] = 95.5;
student_grades[{1, "English"}] = 87.0;
http://www.xdnf.cn/news/1481077.html

相关文章:

  • 嵌入式笔记系列——UART:TTL-UART、RS-232、RS-422、RS-485
  • 旧电脑改造linux服务器2:安装系统
  • 软考中级习题与解答——第二章_程序语言与语言处理程序(3)
  • AD渗透中服务账号相关攻击手法总结(Kerberoasting、委派)
  • 数据仓库概要
  • 【selenium】网页元素找不到?从$(‘[placeholder=“手机号“]‘)说起
  • PyQt5 入门(上):开启 GUI 编程之旅
  • python advance -----object-oriented
  • URI与URL区别:资源ID和地址差异
  • Vue3中Vite的介绍与应用
  • 第1课:开篇:RAG技术与DeepSeek模型全景导读
  • Cloudflare for SaaS 实现 CNAME 接入 CDN 支持国内外智能分流建站
  • AI Agent侵入办公室
  • Android Audio Patch
  • 长尾关键词优化驱动SEO流量增长
  • 链动2+1模式:全渠道整合与用户角色化的商业逻辑与行为动机探析
  • ElasticSearch原理
  • CAN总线学习
  • HarmonyOS:通过组件导航设置信息提醒
  • 贪心算法应用:机器人路径平滑问题详解
  • 9月6日笔记
  • 让机器具有主动性-主动性算法[01]
  • HuggingFace Trainer(回调可视化)
  • 木棉EZ100-Pro 15.5G矿机参数解析:Etchash算法与高效能耗
  • Day27 函数2 装饰器
  • 【Redis】--持久化机制
  • 2025年服装工厂高效管理系统解决方案优选指南
  • 华为悦盒EC6108V9/EC6108V9U/EC6108V9C_MV100(pub普通版/CA高安版)卡刷和强刷固件包
  • 2025年渗透测试面试题总结-55(题目+回答)
  • 为什么ubuntu大文件拷贝会先快后慢?