[C.C++] C++的 tuple

314 0
Honkers 2025-6-27 04:54:12 来自手机 | 显示全部楼层 |阅读模式

1. 基本介绍

tuple 是 C++11 新标准里的类型,它是一个类似 pair 类型的模板。tuple 是一个固定大小的不同类型值的集合,是泛化的 std::pair。我们也可以把它当做一个通用的结构体来用,不需要创建结构体又获取结构体的特征,在某些情况下可以取代结构体使程序更简洁直观。std::tuple 理论上可以有无数个任意类型的成员变量,而 std::pair 只能是2个成员,因此在需要保存3个及以上的数据时就需要使用 tuple 元组,而且每个确定的 tuple 类型的成员数目是固定的。

「注意」:使用tuple的相关操作需要包含相应头文件:#include

一种实现方式:

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. template <typename ... Tail> class Tuple;
  5. template<> class Tuple<> {};
  6. template <typename Head, typename ... Tail>
  7. class Tuple<Head, Tail ...> : Tuple<Tail ...>
  8. {
  9. Head Val;
  10. public:
  11. Tuple() {}
  12. Tuple(Head value, Tail ... tail) : Val(value), Tuple<Tail ...>(tail ...) {}
  13. Head value() { return Val; }
  14. Tuple<Tail ...> next() { return *this; }
  15. };
  16. int main()
  17. {
  18. Tuple<char, double, string> tuple('1', 1.5, "Hello World");
  19. cout << tuple.value() << endl; // 1
  20. cout << tuple.next().value() << endl; // 1.5
  21. cout << tuple.next().next().value() << endl; // Hello World
  22. return 0;
  23. }
复制代码

2. tuple 所支持的操作

  • make_tuple(v1,v2,v3,v4…vn) :返回一个给定初始值初始化的tuple,类型从初始值推断。
  • t1 == t2 :当两个tuple具有相同数量的成员且成员对应相等时。
  • t1 != t2 :与上一个相反。
  • get(t) :返回t的第i个数据成员。
  • tuple_size::value :给定了tuple中成员的数量。

3. 基本用法

3.1 定义和初始化

  1. //使用tuple默认构造函数,创建一个空的tuple对象
  2. tuple<string, int, double> t1;
  3. //使用直接(显式)初始化,不能用“=”初始化
  4. tuple<int, vector<int>> t2(3, { 4, 5, 6 });
  5. //可以用make_tuple()函数生成tuple对象,此处自动推断出t3的类型为tuple<int,int,int>
  6. auto t3 = make_tuple(7, 8, 9);
  7. //tuple的元素类型可以是一个引用
  8. std::tuple<T1&> t4(ref&);
复制代码

3.2 访问

  • 用get标准库模板进行访问其元素内容
  • 用tuple_size访问其元素个数
  • 用tuple_element访问其元素类型
  1. #include<iostream>
  2. #include<string>
  3. #include<tuple>
  4. using namespace std;
  5. int main()
  6. {
  7. auto t1 = make_tuple(1, 2, 3, 4.4);
  8. cout << "第1个元素:" << get<0>(t1) << endl;//和数组一样从0开始计
  9. cout << "第2个元素:" << get<1>(t1) << endl;
  10. cout << "第3个元素:" << get<2>(t1) << endl;
  11. cout << "第4个元素:" << get<3>(t1) << endl;
  12. typedef tuple<int, float, string>TupleType;
  13. cout << tuple_size<TupleType>::value << endl;
  14. tuple_element<1, TupleType>::type fl = 1.0;
  15. return 0;
  16. }
复制代码

输出结果:

  1. 第1个元素:1
  2. 第2个元素:2
  3. 第3个元素:3
  4. 第4个元素:4.4
  5. 3
复制代码

3.3 tuple 比较和 tuple 作为返回值

如果tuple类型进行比较, 则需要保持元素数量相同, 类型可以比较, 如相同类型, 或可以相互转换类型(int&double);

  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <tuple>
  5. using namespace std;
  6. tuple<string, int> giveName()
  7. {
  8. string str("Caroline");
  9. int a(2023);
  10. tuple<string, int> t = make_tuple(str, a);
  11. return t;
  12. }
  13. int main()
  14. {
  15. tuple<int, double, string> t(64, 128.0, "Caroline");
  16. tuple<string, string, int> t2 = make_tuple("Caroline", "Wendy", 1992);
  17. //返回元素个数
  18. size_t num = tuple_size<decltype(t)>::value;
  19. cout << "num = " << num << endl;
  20. //获取第1个值的元素类型
  21. tuple_element<1, decltype(t)>::type cnt = get<1>(t);
  22. cout << "cnt = " << cnt << endl;
  23. //比较
  24. tuple<int, int> t3(24, 48);
  25. tuple<double, double> t4(28.0, 56.0);
  26. bool ret = (t3 < t4);
  27. cout << "ret = " << ret << endl;
  28. //tuple作为返回值
  29. auto t5 = giveName();
  30. cout << "name: " << get<0>(t5) << " years: " << get<1>(t5) << endl;
  31. return 0;
  32. }
复制代码

输出结果:

  1. num = 3
  2. cnt = 128
  3. ret = 1
  4. name: Caroline years: 2023
复制代码

3.4 还有一种方法也可以获取元组的值,通过 std::tie 解包tuple

  1. int x, y;
  2. string s;
  3. std::tie(x, s, y) = t;
复制代码

通过tie解包后,t中三个值会自动赋值给三个变量。

解包时,我们如果只想解某个位置的值时,可以用std::ignore占位符来表示不解某个位置的值。比如我们只想解第三个值时:

  1. std::tie(std::ignore, std::ignore, y) = t; // 只解第三个值
复制代码

3.5 通过 tuple_cat 连接多个 tuple

  1. #include <iostream>
  2. #include <string>
  3. #include <tuple>
  4. using namespace std;
  5. int main()
  6. {
  7. tuple<int, string, float> t1(10, "test", 3.14);
  8. int n = 7;
  9. auto t2 = tuple_cat(t1, make_pair("Foo", "bar"), t1, tie(n));
  10. n = 10;
  11. // 10 test 3.14 Foo bar 10 test 3.14 10
  12. cout << get<0>(t2) << " " << get<1>(t2) << " " << get<2>(t2) << " "
  13. << get<3>(t2) << " " << get<4>(t2) << " " << get<5>(t2) << " "
  14. << get<6>(t2) << " " << get<7>(t2) << " " << get<8>(t2) << endl;
  15. return 0;
  16. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4016
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行