1 键值对std::pair

1.1 基本成员和方法

std::pair将两个值组成一个单元,如下STL容器使用pair作为基本的处理结构(key-value结构)

  • map
  • multimap
  • unordered_map
  • unordered_multimap

std::pair定义在<utility>头文件中,其声明结构如下:

  1. namespace std {
  2. template <typename T1, typename T2>
  3. struct pair {
  4. // member
  5. T1 first;
  6. T2 second;
  7. //...
  8. };
  9. }

pair支持的操作函数如下:
image.png

1.2 构造函数

pair有多个构造函数,其中三个构造函数比较常用。当然更推荐使用std::make_pair()代替构造函数。
image.png
示例如下,主要演示第三个构造的作用:

  1. //std::pair的使用示例
  2. #include <iostream>
  3. #include <utility>
  4. #include <tuple>
  5. using namespace std;
  6. class Foo
  7. {
  8. public:
  9. Foo(tuple<int, float>)
  10. {
  11. cout << "Foo::Foo(tuple)" << endl;
  12. }
  13. template <typename... Args>
  14. Foo(Args... args)
  15. {
  16. cout << "Foo::Foo(args...)" << endl;
  17. }
  18. };
  19. int main()
  20. {
  21. tuple<int, float> t(1, 2.22); //创建一个元组
  22. //构建Foo时,传入t为元组,所以默认使用第一个构造函数
  23. pair<int, Foo> p1(1, t);
  24. //创建pair时限传入了piecewise_construct,表示pair的参数使用不定个数参数的形式
  25. //所以这里,first为42,Foo构建时使用第二个构造函数
  26. pair<int, Foo> p2(std::piecewise_construct, make_tuple(2), t);
  27. //打印一下pair的key-value
  28. cout << p1.first << endl;//直接打印first,second
  29. cout << get<0>(p2) << endl;//使用get模板函数
  30. }

2 元组std::tuple

2.1 创建和访问

元组在C++11开始得到了全面支持,可以包含任意数量的类型,是pair的进阶版(pair只能容纳两个类型)。定义如下:

  1. template<typename... _Elements>//变长模板,可以接收任意数量类型
  2. class tuple : public _Tuple_impl<0, _Elements...>
  3. {};

tuple的基本使用和pair一样:

  • 通过构造函数或make_tuple()创建tuple
  • 通过get<>()获取元组的不同成员或重新赋值,注意get中的索引必须是确定的,不能传入运行时索引值(比如for i)
  • 使用tie()解包提取元组的成员为独立的变量,并通过std::ignore略过不需要的成员 ```cpp //创建并初始化tuple tuple t1{41, 6.3, “nice”}; //打印值 cout << get<0>(t1) << “ “; cout << get<1>(t1) << “ “; cout << get<2>(t1) << “ “; cout << endl;

//使用make_tuple创建tuple auto t2 = make_tuple(22, 33, “nice”); cout << get<0>(t2) << “ “; cout << get<1>(t2) << “ “; cout << get<2>(t2) << “ “; cout << endl;

//给元组第二个值赋值 get<1>(t1) = 44; cout << get<1>(t1) << “ “;

//比较元组大小 cout << “is t1 > t2: “ << (t1 > t2) << endl;

//使用tie解包 int a; string s; std::tie(a, std::ignore, s) = t1; //ignore为略过部分成员 cout << a << “ “ << s << endl;

  1. <a name="EZg9e"></a>
  2. ## 2.2 重载<<打印元组
  3. ```cpp
  4. //重载<<运算符,支持打印tuple
  5. #include <tuple>
  6. #include <iostream>
  7. template <int IDX, int MAX, typename... Args>
  8. class PRINT_TUPLE
  9. {
  10. public:
  11. static void print(std::ostream &strm, const std::tuple<Args...> &t)
  12. {
  13. strm << std::get<IDX>(t) << (IDX + 1 == MAX ? "" : ",");
  14. PRINT_TUPLE<IDX + 1, MAX, Args...>::print(strm, t);
  15. }
  16. };
  17. template <int MAX, typename... Args>
  18. class PRINT_TUPLE<MAX, MAX, Args...>
  19. {
  20. public:
  21. static void print(std::ostream &strm, const std::tuple<Args...> &t)
  22. {
  23. //最后一个,什么都不需要打印
  24. }
  25. };
  26. template <typename... Args>
  27. std::ostream &operator<<(std::ostream &strm, const std::tuple<Args...> &t)
  28. {
  29. strm << "[";
  30. PRINT_TUPLE<0, sizeof...(Args), Args...>::print(strm, t);
  31. return strm << "]";
  32. }