1 键值对std::pair
1.1 基本成员和方法
std::pair将两个值组成一个单元,如下STL容器使用pair作为基本的处理结构(key-value结构)
- map
- multimap
- unordered_map
- unordered_multimap
std::pair定义在<utility>头文件中,其声明结构如下:
namespace std {template <typename T1, typename T2>struct pair {// memberT1 first;T2 second;//...};}
1.2 构造函数
pair有多个构造函数,其中三个构造函数比较常用。当然更推荐使用std::make_pair()代替构造函数。
示例如下,主要演示第三个构造的作用:
//std::pair的使用示例#include <iostream>#include <utility>#include <tuple>using namespace std;class Foo{public:Foo(tuple<int, float>){cout << "Foo::Foo(tuple)" << endl;}template <typename... Args>Foo(Args... args){cout << "Foo::Foo(args...)" << endl;}};int main(){tuple<int, float> t(1, 2.22); //创建一个元组//构建Foo时,传入t为元组,所以默认使用第一个构造函数pair<int, Foo> p1(1, t);//创建pair时限传入了piecewise_construct,表示pair的参数使用不定个数参数的形式//所以这里,first为42,Foo构建时使用第二个构造函数pair<int, Foo> p2(std::piecewise_construct, make_tuple(2), t);//打印一下pair的key-valuecout << p1.first << endl;//直接打印first,secondcout << get<0>(p2) << endl;//使用get模板函数}
2 元组std::tuple
2.1 创建和访问
元组在C++11开始得到了全面支持,可以包含任意数量的类型,是pair的进阶版(pair只能容纳两个类型)。定义如下:
template<typename... _Elements>//变长模板,可以接收任意数量类型class tuple : public _Tuple_impl<0, _Elements...>{};
tuple的基本使用和pair一样:
- 通过构造函数或
make_tuple()创建tuple - 通过
get<>()获取元组的不同成员或重新赋值,注意get中的索引必须是确定的,不能传入运行时索引值(比如for i) - 使用
tie()解包提取元组的成员为独立的变量,并通过std::ignore略过不需要的成员 ```cpp //创建并初始化tuple tuplet1{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;
<a name="EZg9e"></a>## 2.2 重载<<打印元组```cpp//重载<<运算符,支持打印tuple#include <tuple>#include <iostream>template <int IDX, int MAX, typename... Args>class PRINT_TUPLE{public:static void print(std::ostream &strm, const std::tuple<Args...> &t){strm << std::get<IDX>(t) << (IDX + 1 == MAX ? "" : ",");PRINT_TUPLE<IDX + 1, MAX, Args...>::print(strm, t);}};template <int MAX, typename... Args>class PRINT_TUPLE<MAX, MAX, Args...>{public:static void print(std::ostream &strm, const std::tuple<Args...> &t){//最后一个,什么都不需要打印}};template <typename... Args>std::ostream &operator<<(std::ostream &strm, const std::tuple<Args...> &t){strm << "[";PRINT_TUPLE<0, sizeof...(Args), Args...>::print(strm, t);return strm << "]";}
