类pair提供了这样一种机制,它把两个(有序)值作为一个单元对待.在c++标准库中,它被广泛的应用.特别是在容器类map和multimap中大量的使用了pair来管理它们的元素.另外一个对于pair的广泛使用就是在那些要返回两个值的函数中.
结构pair被定义在<utility>中,如下:
namespace std {
template <class T1, class T2>
struct pair {
//type names for the values
typedef T1 first_type;
typedef T2 second_type;
//member
T1 first;
T2 second;
/* default constructor
* - T1 () and T2 () force initialization for built-in types
*/
pair()
: first(T1()), second(T2()) {
}
//constructor for two values
pair(const T1& a, const T2& b)
: first(a), second(b) {
}
//copy constructor with implicit conversions
template<class U, class V>
pair(const pair<U,V>& p)
: first(p.first), second(p.second) {
}
};
//comparisons
template <class T1, class T2>
bool operator== (const pair<T1,T2>&, const pair<T1,T2>&);
template <class T1, class T2>
bool operator< (const pair<T1,T2>&, const pair<T1,T2>&);
//similar: !=, <=, >, >=
//convenience function to create a pair
template <class T1, class T2>
pair<T1,T2> make_pair (const T1&, const T2&);
}
注意pair被定义为struct而不是class,这就是说访问pair中任何一个单独的值都是可以的.默认的构造函数会调用模板类型中默认的构造函数.当然,它也会初始化基本类型如int为默认的值.比如:
std::pair<int,float> p;
这样的结果就是p.first=0,p.second=0
上面的带模板的拷贝构造函数是在隐式类型转换的时候使用的.如:
void f(std::pair<int,const char*>);
void g(std::pair<const int.std::string>);
void foo {
std::pair<int,const char*> p(42,"hello");
f(p); //OK: calls built-in default copy constructor
g(p); //OK: calls template constructor
}
上面的例子还不能说明问题,下面我自己实现一个pair:
template <class T1,class T2>
class MyPair
{
public:
T1 first;
T2 second;
MyPair():first(T1()),second(T2())
{
std::cout<<"first constructor"<<std::endl;
}
MyPair(const T1& a,const T2&b):first(a),second(b)
{
std::cout<<"second constructor"<<std::endl;
}
template<class U,class V>
MyPair(const MyPair<U,V> &myP):first(myP.first),second(myP.second)
{
std::cout<<"third constructor"<<std::endl;
}
};
相应f()和g()也进行一番改动:
void f(MyPair<int,const char*> arg)
{
std::cout<<arg.first<<","<<arg.second<<std::endl;
}
void g(MyPair<int,std::string> arg)
{
std::cout<<arg.first<<","<<arg.second<<std::endl;
}
这是调用过程:
int main()
{
MyPair<int,const char*> p(100,"Hello World");
f(p);
g(p);
}
这是调用结果:
second constructor
100,Hello World
third constructor
100,Hello World
可以看到f(p)的参数的模板类与之前构造的模板类相同,所以会调用默认的构造函数进行复制.
但是g(p)的参数的模板类与之前构造的模板类不同,所以会调用带模板定义的拷贝构造函数进行复制.
序偶的比较
两个序偶相同,当且仅当两个序偶中对应的值相同.
namespace std {
template <class T1, class T2>
bool operator== (const pair<T1,T2>& x, const pair<T1,T2>& y) {
return x.first == y.first && x.second == y.second;
}
}
比较两个序偶的大小,第一个元素有较高的优先级,第一个元素小的序偶小,如果第一个元素相等,则比较第二个.
namespace std {
template <class T1, class 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);
}
}
一个方便的构造序偶的函数make_pair
std::make_pair(42,'@')可以用来取代std::pair<int,char>(42.'@')
make_pair的定义:
namespace std {
//create value pair only by providing the values
template <class T1, class T2>
pair<Tl,T2> make_pair (const T1& x, const T2& y) {
return pair<T1,T2>(x, y);
}
}
但是在某些情况下,你可能需要显式的定义类型,这个时候make_pair往往不会产生预期的结果:
std::pair<int,float>(42,7.77)
与
std::make_pair(42,7.77)
所产生的pair并不相同,因为后者等效于std::pair<int,
double>(42,7,77)
posted on 2007-07-03 23:49
littlegai 阅读(303)
评论(0) 编辑 收藏 引用