The C++ Standard Library : A Tutoral and Reference 读书笔记之序偶(Pair)

The C++ Standard Library : A Tutoral and Reference 读书笔记之序偶(Pair)
类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)

你可能感兴趣的:(The C++ Standard Library : A Tutoral and Reference 读书笔记之序偶(Pair))