C++ - Pairs 和 Tuples

一、Pairs

1. 定义

Pairs为一个结构体,这样它的所有成员都是public的。可以更加方便的进行访问。

namespace std {
    template <typename T1, typename T2>
    struct pair {
        //member
        T1 first;
        T2 second;
    }
}

2. 操作

OperationEffect
pair<T1, T2>创建一个pair并使用类型T1和T2的默认构造器来初始化元素
pair<T1, T2> p(val1, val2)创建一个pair并使用val1和val2来初始化元素
pair<T1, T2> p(piecewise_construct, t1, t2)创建一个pair并使用tuples的t1和t2来初始化元素
pair<T1, T2> p(p2)Copy 构造器
pair<T1, T2> p(rv1, rv2)创建一个pair并使用rv1和rv2来move初始化元素
pair<T1, T2> p(rv)Move 构造器
p = p2将p2赋值给p
p = rv将rv移动赋值给p
p.first p.second访问p的第一和第二个元素
get<0>(p) get<1>(p)p.first p.second 相同 (C++11提出的)
p1 == p2当p1和p2的first和second都相等的时候p1和p2相等
p1 != p2当p1和p2的first和second有一个不相等的时候,p1和p2不相等
p1 < p2当p1的first小于p2的first,或者当first相等p1的second小于p2的second的时候p1 < p2。
p1 <= p2当p1的first小于等于p2的first,或者当first相等p1的second小于等于p2的second的时候p1 < p2
p1.swap(p2)交换p1和p2的值(c++11)
swap(p1, p2)使用全局swap函数交换p1和p2的值(c++11)
make_pair(val1, val2)返回一个使用val1和val2的类型和值构建的pair

move是C++11提出的一个新的概念,可以参考教程—

其中c++11为Pairs添加了一些额外的内容。
1. 支持move构造和赋值
2. 支持隐式类型转换构造和赋值
3. 支持tuple的构造

3. make_pair函数定义

make_pair是使用最多的一个函数,通过该函数我们可以直接返回一个pairs

  • 如下为c++11之前的make_pair函数定义。
namespace std {
    template <template T1, template T2>
    pair<T1, T2> make_pair(const T1& x, const T2& y) {
        return pair<T1, T2>(x, y);
    }
}

并且由于该函数使用了函数模板,所在不需要指定参数类型。
因此对于 std::pair<int, char>(4, 'a') 可以写成 std::make_pair(4, 'a')

  • c++11的make_pair函数定义则引入了move的概念,其定义如下
namespace std {
    template <template T1, template T2>
    pair<T1, T2> make_pair(const T1&& x, const T2&& y) {
        return pair<T1, T2>(x, y);
    }
}
  • 这里我们可以通过使用std::move()来强制使用move语义
std::string s, t;
...
auto p = std::make_pair(std::move(s), std::move(t));
...
  • std::ref()来强制使用ref语义
std::int i, j;
...
auto p = std::make_pair(std::ref(i), std::ref(j));
++p.first;
++i;
std::cout << "i = " << i << std::endl; // i = 2
...

4. Pair的比较

  • 判断两个pair是否相等的定义如下:
namespace std {
    template <typename T1, typename T2>
    bool operator== (const pair<T1, T2>& x, const pair<T1, T2>& y) {
        return x.first == y.first && x.second == y.second;
    }
}

从定义中我们可以看到只有当pair的first和second都相等的时候,两个pair才会相等。

  • 判断两个pair的大小的定义如下:
namesapce std {
    template <typename T1, typename T2> 
    bool operator< (const pair<T1, T2>& x, const pair<T1, T2>& y) {
        return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
    }
}

从定义中我们可以看到在比较大小的时候first元素具有高优先级,即如果first可以比较出大小则结束,否则继续比较second元素的大小。

二、Tuples

相对于 pairs 来说,tuples 可以有多个元素。

1. 定义

namespace std {
    template <typename... Types> //c++11 表示多个参数模板
    class tuple {
      public:
        explicit tuple(const Types&...); //显示构造函数
        template <typename... UTypes> explicit tuple(UTypes&&...); //显示构造函数, move语义, 隐式的类型转换
        ...
    }
}

从定义我们可以看出,tuple可以接受任意多个参数,支持move语义和隐式类型转换。并且需要被显示的构造。

2. 操作

OperationEffect
tuple<T1, T2, ..., Tn>创建一个tuple并使用类型T1-Tn的默认构造器来分别初始化元素
tuple<T1, T2, ..., Tn> p(val1, val2, ..., valn)创建一个tuple并使用val1, val2, …, valn来分别初始化对应的元素
tuple<T1, T2> t(p)对于只有两个元素的tuple可以使用一个pair来进行构造
t = t2将t2赋值给t
t1 == t2当t1和t2的所有元素都相等的时候t1和t2相等
t1 != t2当t1和t2的元素有一个不相等的时候,t1和t2不相等
t1 < t2从第一个元素开始比较,只要当前元素可以判断出是否小于就返回
t1 <= t2从第一个元素开始比较,只要当前元素可以判断出是否小于等于就返回
t1.swap(t2)交换t1和t2的值(c++11)
swap(t1, t2)使用全局swap函数交换t1和t2的值(c++11)
make_tuple(v1, v2, ..., )返回一个使用v1,v2,…的类型和值d的一个tuple
tie(ref1, ref2,...)返回一个使用v1, v2,…的类型以及使用引用赋值的一个tuple
  • *make_tuple 函数。make_tuple是使用比较频繁的一个函数。如下为该函数的使用举例:
string s;
make_tuple(s); //默认构造
make_tuple(ref(s)) //使用引用构造
make_tuple(move(s)) //使用move语义进行构造
  • *get<index>(tuple) 该函数是得到tuple的第index个元素。如下为该函数的使用举例:
tuple<int, float, string> t(77, 1.1, "hello world");
auto x = get<0>(t) // 取值, x = 77
get<0>(t) = 11     // 赋值, t的第0个元素的值变为11
  • *tie(ref1,ref2,...) 该函数是为tuple的每一个元素建立一个外部引用。举例如下。
tuple<int, float, string> t(77, 1.1, "hello world");
int i;
float f;
string s;
tie(i, f, s) = t;  //将t中的每一个元素和外部的一个变量进行绑定

这里我们可以使用ignore关键字来对tie中的某一个元素进行缺省。如下。

tuple<int, float, string> t(77, 1.1, "hello world");
int i;
string s;
tie(i, ignore, s) = t;  //将t中的每一个元素和外部的一个变量进行绑定
  • *额外的几个函数:
    1. tuple_size<tupletype>::value 得到该tuple的元素个数
    2. tuple_element<idx, typletype>::type 得到该tuple的第idx的元素类型
    3. tuple_cat() 将多个tuple合成为一个tuple
typedef tuple<int, float, string> TupleType;

tuple_size<TupleType>::value   // 3
tupel_element<1, TupleType>::type // float

int n;
auto tt = tuple_cat(make_tuple(4,1.1,"hello"), tie(n)); //
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值