今天再看《c++标准库》,遇到了以前貌似有点印象的pair,特意记录下来,免得以后忘记了。下面是在vs查看pair定义的一部分代码(貌似很多,只贴一部分)
template<class _Ty1,
class _Ty2>
struct pair
: public _Pair_base<_Ty1, _Ty2>
{ // store a pair of values
typedef _Pair_base<_Ty1, _Ty2> _Mybase;
typedef pair<_Ty1, _Ty2> _Myt;
typedef _Ty1 first_type;
typedef _Ty2 second_type;
pair()
: _Mybase()
{ // construct from defaults
}
pair(const _Ty1& _Val1, const _Ty2& _Val2)
: _Mybase(_Val1, _Val2)
{ // construct from specified values
}
template<class _Other1,
class _Other2>
pair(pair<_Other1, _Other2>& _Right)
: _Mybase(_Right.first, _Right.second)
{ // construct from compatible pair
}
template<class _Other1,
class _Other2>
pair(const pair<_Other1, _Other2>& _Right)
: _Mybase(_Right.first, _Right.second)
{ // construct from compatible pair
}
void swap(_Myt& _Right)
{ // exchange contents with _Right
if (this != &_Right)
{ // different, worth swapping
_Swap_adl(this->first, _Right.first);
_Swap_adl(this->second, _Right.second);
}
}
_Myt& operator=(const _Myt& _Right)
{ // assign from copied pair
this->first = _Right.first;
this->second = _Right.second;
return (*this);
}
typedef typename tr1::remove_reference<_Ty1>::type _Ty1x;
typedef typename tr1::remove_reference<_Ty2>::type _Ty2x;
pair(_Ty1x&& _Val1, _Ty2x&& _Val2)
: _Mybase(_STD move(_Val1),
_STD move(_Val2))
{ // construct from specified values
}
pair(const _Ty1x& _Val1, _Ty2x&& _Val2)
: _Mybase(_Val1,
_STD move(_Val2))
{ // construct from specified values
}
pair(_Ty1x&& _Val1, const _Ty2x& _Val2)
: _Mybase(_STD move(_Val1),
_Val2)
{ // construct from specified values
}
template<class _Other1,
class _Other2>
pair(_Other1&& _Val1, _Other2&& _Val2)
: _Mybase(_STD forward<_Other1>(_Val1),
_STD forward<_Other2>(_Val2))
{ // construct from moved values
}
template<class _Other1,
class _Other2>
pair(pair<_Other1, _Other2>&& _Right)
: _Mybase(_STD forward<_Other1>(_Right.first),
_STD forward<_Other2>(_Right.second))
{ // construct from moved compatible pair
}
pair& operator=(pair<_Ty1, _Ty2>&& _Right)
{ // assign from moved pair
this->first = _STD move(_Right.first);
this->second = _STD move(_Right.second);
return (*this);
}
void swap(_Myt&& _Right)
{ // exchange contents with _Right
if (this != &_Right)
{ // different, worth swapping
this->first = _STD move(_Right.first);
this->second = _STD move(_Right.second);
}
}
};
// pair TEMPLATE FUNCTIONS
template<class _Ty1,
class _Ty2> inline
void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>& _Right)
{ // swap _Left and _Right pairs
_Left.swap(_Right);
}
template<class _Ty1,
class _Ty2> inline
void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>&& _Right)
{ // swap _Left and _Right pairs
typedef pair<_Ty1, _Ty2> _Myt;
_Left.swap(_STD forward<_Myt>(_Right));
}
template<class _Ty1,
class _Ty2> inline
void swap(pair<_Ty1, _Ty2>&& _Left, pair<_Ty1, _Ty2>& _Right)
{ // swap _Left and _Right pairs
typedef pair<_Ty1, _Ty2> _Myt;
_Right.swap(_STD forward<_Myt>(_Left));
}
template<class _Ty1,
class _Ty2> inline
bool operator==(const pair<_Ty1, _Ty2>& _Left,
const pair<_Ty1, _Ty2>& _Right)
{ // test for pair equality
return (_Left.first == _Right.first && _Left.second == _Right.second);
}
template<class _Ty1,
class _Ty2> inline
bool operator!=(const pair<_Ty1, _Ty2>& _Left,
const pair<_Ty1, _Ty2>& _Right)
{ // test for pair inequality
return (!(_Left == _Right));
}
template<class _Ty1,
class _Ty2> inline
bool operator<(const pair<_Ty1, _Ty2>& _Left,
const pair<_Ty1, _Ty2>& _Right)
{ // test if _Left < _Right for pairs
return (_Left.first < _Right.first ||
!(_Right.first < _Left.first) && _Left.second < _Right.second);
}
template<class _Ty1,
class _Ty2> inline
bool operator>(const pair<_Ty1, _Ty2>& _Left,
const pair<_Ty1, _Ty2>& _Right)
{ // test if _Left > _Right for pairs
return (_Right < _Left);
}
template<class _Ty1,
class _Ty2> inline
bool operator<=(const pair<_Ty1, _Ty2>& _Left,
const pair<_Ty1, _Ty2>& _Right)
{ // test if _Left <= _Right for pairs
return (!(_Right < _Left));
}
template<class _Ty1,
class _Ty2> inline
bool operator>=(const pair<_Ty1, _Ty2>& _Left,
const pair<_Ty1, _Ty2>& _Right)
{ // test if _Left >= _Right for pairs
return (!(_Left < _Right));
}
// TEMPLATE FUNCTION make_pair
template<class _Ty1,
class _Ty2> inline
pair<typename _Unrefwrap<_Ty1>::type,
typename _Unrefwrap<_Ty2>::type>
make_pair(_Ty1&& _Val1, _Ty2&& _Val2)
{ // return pair composed from arguments
typedef pair<typename _Unrefwrap<_Ty1>::type,
typename _Unrefwrap<_Ty2>::type> _Mypair;
return (_Mypair(_STD forward<_Ty1>(_Val1),
_STD forward<_Ty2>(_Val2)));
}
template<class _Ty1,
class _Ty2> inline
pair<typename _Unrefwrap<_Ty1>::type,
typename _Unrefwrap<_Ty2>::type>
make_pair(const _Ty1& _Val1, _Ty2&& _Val2)
{ // return pair composed from arguments
typedef pair<typename _Unrefwrap<_Ty1>::type,
typename _Unrefwrap<_Ty2>::type> _Mypair;
return (_Mypair((typename _Unrefwrap<_Ty1>::type)_Val1,
_STD forward<_Ty2>(_Val2)));
}
template<class _Ty1,
class _Ty2> inline
pair<typename _Unrefwrap<_Ty1>::type,
typename _Unrefwrap<_Ty2>::type>
make_pair(_Ty1&& _Val1, const _Ty2& _Val2)
{ // return pair composed from arguments
typedef pair<typename _Unrefwrap<_Ty1>::type,
typename _Unrefwrap<_Ty2>::type> _Mypair;
return (_Mypair(_STD forward<_Ty1>(_Val1),
(typename _Unrefwrap<_Ty2>::type)_Val2));
}
template<class _Ty1,
class _Ty2> inline
pair<typename _Unrefwrap<_Ty1>::type,
typename _Unrefwrap<_Ty2>::type>
make_pair(const _Ty1& _Val1, const _Ty2& _Val2)
{ // return pair composed from arguments
typedef pair<typename _Unrefwrap<_Ty1>::type,
typename _Unrefwrap<_Ty2>::type> _Mypair;
return (_Mypair((typename _Unrefwrap<_Ty1>::type)_Val1,
(typename _Unrefwrap<_Ty2>::type)_Val2));
}
#if _HAS_CPP0X
template<class _InIt> inline
_InIt begin(const pair<_InIt, _InIt>& _Pair)
{ // return first element of pair
return (_Pair.first);
}
template<class _InIt> inline
_InIt end(const pair<_InIt, _InIt>& _Pair)
{ // return second element of pair
return (_Pair.second);
}
#endif /* _HAS_CPP0X */
// TEMPLATE OPERATORS
namespace rel_ops
{ // nested namespace to hide relational operators from std
template<class _Ty> inline
bool operator!=(const _Ty& _Left, const _Ty& _Right)
{ // test for inequality, in terms of equality
return (!(_Left == _Right));
}
很乱是吧(ps:我也不知道贴的对不对,哈哈...)不过从上面的代码中大概可以看出,它已经帮我们实现了一些基本的运行,例如swap(两个pair数据的交换),还有paire的比较等。下面是测试代码(环境vs2010):
#include <iostream>
#include <utility>//使用pair需要添加此文件才能识别
#include <string>
using namespace std;
int main()
{
cout<<"Hello ,STL Paire"<<endl;
pair<string,int>p1 ("vegetables",4);
pair<string,int>p2;
p2.first = "people";
p2.second = 5.99;
pair<string,double>p3 = make_pair("lining",361.0);
pair<string,int>p4 = make_pair("anta",400);
cout<<"p1.first:"<<p1.first<<" ,p1.second:"<<p1.second<<endl;
cout<<"p2.first:"<<p2.first<<" ,p2.second:"<<p2.second<<endl;
cout<<"p3.first:"<<p3.first<<" ,p3.second:"<<p2.second<<endl;
p2.swap(p1);//交换两个paire值
cout<<"p1.first:"<<p1.first<<" ,p1.second:"<<p1.second<<endl;
cout<<"p2.first:"<<p2.first<<" ,p2.second:"<<p2.second<<endl;
cout<<"p2<p1 is "<<(p2<p1)<<endl;//源码已经重载了<,>,==等一些运算。
//cout<<"p3<p4 is "<<(p3<p4)<<endl//这里如果这样,编译不过去,貌似比较的两个pair值得键和值的类型都一样,如果改成一样就可以编译过去了
system("pause");
return 0;
}
输出结果:
注:STL容器中的map和mutimap就是使用pairs来管理键值对。任何函数需要返回两个值,也需要pair.还有就是两个pair互相比较时,第一元素具有较高的优先级。所以两个pairs的的第一元素不相等,其比较结果就成为整个比较行为的结果。如果第一元素相等,才继续比较第二元素,并把比较结果当做整体比较结果。
好了,睡觉,明天继续加油啃《c++标准库》。