当前位置:   article > 正文

c++新特性 深入元组_c++ sequence

c++ sequence

1.元组简介

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

    tuple(元组)在c++11中开始引用的。tuple看似简单,其实它是简约而不简单,可以说它是c++11中一个既简单又复杂的东东,关于它简单的一面是它很容易使用,复杂的一面是它内部隐藏了太多细节,要揭开它神秘的面纱时又比较困难。

2.tuple的创建以及初始化

std::string name;
std::tuple<string &, int> tpRef(name, 30);
// 对tpRef第一个元素赋值,同时name也被赋值 - 引用
std::get<0>(tpRef) = "Sven";
 
// name输出也是Sven
std::cout << "name: " << name << '\n';

 3.有关tuple的操作

 3.1等价结构体

     开篇讲过在某些时候tuple可以等同于结构体一样使用,这样既方便又快捷。如

  1. struct person {
  2. char *m_name;
  3. char *m_addr;
  4. int *m_ages;
  5. };
  6. //可以用tuple来表示这样的一个结构类型,作用是一样的。
  7. std::tuple<const char *, const char *, int>

 3.2获取元组取个数和合并元组

tuple_size<decltype(u)>::value;

tuple_cat;

  1. #include<tuple>
  2. #include<iostream>
  3. int main()
  4. {
  5. std::tuple<double,char,std::string> u(2.6,'c',"王五");
  6. std::cout<<std::tuple_size<decltype(u)>::value<<std::endl;
  7. std::tuple<double,char,std::string> v(1.6,'d',"陈六");
  8. auto new_tuple=std::tuple_cat(std::move(u),std::move(v));
  9. std::cout<<std::get<5>(new_tuple)<<"\n";
  10. }

3.3获取元组类型

  1. std::tuple<std::string, int> tp("Sven", 20);
  2. // 得到第二个元素类型
  3. std::tuple_element<1, decltype(tp)>::type ages; // ages就为int类型
  4. ages = std::get<1>(tp);
  5. std::cout << "ages: " << ages << '\n';
  6. //输出结果:
  7. ages: 20

3.4解包和引用

  1. #include<tuple>
  2. #include<iostream>
  3. #include<variant>
  4. auto get_student(int id)
  5. {
  6. if(id==0)
  7. return std::make_tuple(3.8,'A',"张三");
  8. if(id==1)
  9. return std::make_tuple(3.3,'c',"李四");
  10. if(id==2)
  11. return std::make_tuple(2.9,'d',"王五");
  12. return std::make_tuple(0.0,'D',"null");
  13. }
  14. int main()
  15. {
  16. auto student=get_student(0);
  17. std::cout << "ID: 0, "
  18. << "GPA: " << std::get<0>(student) << ", "
  19. << " 成绩: " << std::get<1>(student) << ", "
  20. << " 姓名: " << std::get<2>(student) << '\n';
  21. double gpa;
  22. char grade;
  23. std::string name;
  24. std::tie(gpa,grade,name)=get_student(1);
  25. std::cout << "ID: 1, "
  26. << "GPA: " << gpa << ", "
  27. << " 成绩: " << grade << ", "
  28. << " 姓名: " << name << "\n";
  29. }
  30. //output
  31. ID: 0, GPA: 3.8, 成绩: A, 姓名: 张三
  32. ID: 1, GPA: 3.3, 成绩: c, 姓名: 李四

但有时候tuple包含的多个元素时只需要其中的一个或两个元素,如此可以通过std::ignore进行变量占位,这样将会忽略提取对应的元素

  1. #include <iostream>
  2. #include <tuple>
  3. #include <utility>
  4. int main(int argc, char **argv) {
  5. std::tuple<std::string, int, std::string, int> tp;
  6. tp = std::make_tuple("Sven", 25, "Shanghai", 21);
  7. // 定义接收变量
  8. std::string name;
  9. std::string addr;
  10. int ages;
  11. int areaCode = 110;
  12. std::tie(name, ages, std::ignore, std::ignore) = tp;
  13. std::cout << "Output: " << '\n';
  14. std::cout << "name: " << name <<", ";
  15. std::cout << "addr: " << addr << ", ";
  16. std::cout << "ages: " << ages << ", ";
  17. std::cout << "areaCode: " << areaCode << '\n';
  18. return 0;
  19. }
  20. //输出结果:
  21. Output:
  22. name: Sven, addr: , ages: 25, areaCode: 110

3.5遍历

tuple不支持迭代,只能通过元素索引(或tie解包)进行获取元素的值。但是给定的索引必须是在编译器就已经给定,不能在运行期进行动态传递,否则将发生编译错误:

tuple不支持迭代,只能通过元素索引(或tie解包)进行获取元素的值。但是给定的索引必须是在编译器就已经给定,不能在运行期进行动态传递,否则将发生编译错误:

 正确遍历:

  1. // 帮助程序用于将元组转换为可变参数模板函数参数
  2. // sequence_generator<3>::type will be sequence<0, 1, 2>.
  3. template <int...>
  4. struct sequence {};
  5. template <int N, int... S>
  6. struct sequence_generator : sequence_generator<N - 1, N - 1, S...> {};
  7. template <int... S>
  8. struct sequence_generator<0, S...> {
  9. typedef sequence<S...> type;
  10. };
  11. template<typename T, typename F, int... S>
  12. void for_each(T&& t, F f, sequence<S...>)
  13. {
  14. auto l = { (f(std::get<S>(t)), 0)... };
  15. }
  16. template<typename... Args, typename F>
  17. void for_each_in_tuple(std::tuple<Args...> const& t, F f)
  18. {
  19. for_each(t, f, typename sequence_generator<sizeof...(Args)>::type());
  20. }
  21. struct functor {
  22. template<typename T>
  23. void operator()(T&& t)
  24. {
  25. std::cout << t << std::endl;
  26. }
  27. };
  28. int main()
  29. {
  30. std::tuple<double, char, std::string> t = std::make_tuple(3.14, 'A', "StoneLiu");
  31. for_each_in_tuple(t, functor());
  32. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/305841
推荐阅读
相关标签
  

闽ICP备14008679号