STL中的模板类pair ,make_pair和map

1 pair的应用

pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。

2 make_pair函数

?
1
template pair make_pair(T1 a, T2 b) { return pair(a, b); }

很明显,我们可以使用pair的构造函数也可以使用make_pair来生成我们需要的pair。 一般make_pair都使用在需要pair做参数的位置,可以直接调用make_pair生成pair对象很方便,代码也很清晰。 另一个使用的方面就是pair可以接受隐式的类型转换,这样可以获得更高的灵活度。灵活度也带来了一些问题如:

?
1
2
std::pair< int , float >(1, 1.1);
std::make_pair(1, 1.1);



是不同的,第一个就是float,而第2个会自己匹配成double。

 

STL的<utility>头文件中描述了一个非常简单的模板类pair,用来表示一个二元组或元素对,并提供了大小比较的比较运算符模板函数。

pair模板类需要两个参数:首元素的数据类型和尾元素的数据类型。pair模板类对象有两个成员:first和second,分别表示首元素和尾元素。

在<utility>中已经定义了pair上的六个比较运算符:<、>、<=、>=、==、!=,其规则是先比较first,first相等时再比较second,这符合大多数应用的逻辑。当然,也可以通过重载这几个运算符来重新指定自己的比较逻辑。

  • 例子程序:
  • [c-sharp] view plain copy print ?
    1. // map/pair-test.cpp - Show basic use of pair.    
    2. // 2004-02-29 - Fred Swartz - Rodenbach    
    3.    
    4. #include <utility>    
    5. #include <iostream>    
    6. #include <string>    
    7. #include <map>     
    8. using namespace std;    
    9.     
    10. int main() {    
    11.     //-- Declare a pair variable.    
    12.     pair<stringint> pr1;    
    13.         
    14.     //-- Declare and initialize with constructor.    
    15.     pair<stringint> pr2("heaven", 7);    
    16.     cout << pr2.first << "=" << pr2.second << endl;    
    17.     // Prints heaven=7     
    18.         
    19.     //-- Declare and initialize pair pointer.    
    20.     pair<stringint>* prp = new pair<stringint>("yards", 9);    
    21.     cout << prp->first << "=" << prp->second << endl;    
    22.     // Prints yards=9     
    23.         
    24.     //-- Declare map and assign value to keys.    
    25.     map<stringstring> engGerDict;    
    26.     engGerDict["shoe"] = "Schuh";    
    27.     engGerDict["head"] = "Kopf";    
    28.         
    29.     //-- Iterate over map.  Iterator value is a key-value pair.    
    30.     //   Iteration in map is in sorted order.    
    31.     map<stringstring>::const_iterator it;    
    32.     for (it=engGerDict.begin(); it != engGerDict.end(); ++it) {    
    33.         cout << it->first << "=" << it->second << endl;    
    34.     }    
    35.     // Prints head=kopf     
    36.     //        shoe=Schuh     
    37.         
    38.     system("PAUSE");    
    39.     return 0;    
    40. }    
     
  • 除了直接定义一个pair对象外,如果需要即时生成一个pair对象,也可以调用在<utility>中定义的一个模板函数:make_pair。make_pair需要两个参数,分别为元素对的首元素和尾元素。

    • 例子程序:
    • [c-sharp] view plain copy print ?
      1. // mkpair.cpp     
      2. // compile with: /EHsc     
      3. // Illustrates how to use the make_pair function.    
      4. //     
      5. // Functions: make_pair - creates an object pair containing two data    
      6. //                        elements of any type.    
      7.     
      8. ========make_pair    
      9. #include <utility>    
      10. #include <iostream>     
      11.     
      12. using namespace std;    
      13.     
      14. /* STL pair data type containing int and float  
      15. */    
      16.     
      17. typedef struct pair<int,float> PAIR_IF;    
      18.     
      19. int main(void)    
      20. {    
      21.   PAIR_IF pair1=make_pair(18,3.14f);    
      22.     
      23.   cout << pair1.first << "  " << pair1.second << endl;    
      24.   pair1.first=10;    
      25.   pair1.second=1.0f;    
      26.   cout << pair1.first << "  " << pair1.second << endl;    
      27. }    
  1. // pair简单讲就是将两个数据整合成一个数据
    // 本质上是有first, second两个成员变量的结构体
    extern void test_pair()
    {
    	// pair两种构造的方法
    	// 方法1
    	std::pair<std::string, double>("This is a StringTest0.", 9.7);	// 浮点数默认是double, float的话有会警告。
    	std::pair<std::string, double> pA("This is a StringTest.", 9.7);
    	// 方法2
    	std::pair<std::string, double> pB;
    	pB = std::make_pair("This is a StringTest.", 9.9);
    	
    	// pair的输出
    	std::cout << pA.first << std::endl;
    	std::cout << pA.second << std::endl;
    
    	// 结合map的使用
    	std::map<std::string, double> mA;
    	mA.insert(pA);
    	mA.insert(pB);
    
    	for (std::map<std::string, double>::iterator it = mA.begin(); it != mA.end(); ++it)
    	{
    		std::cout << "First Member:  " << it->first << std::endl;
    		std::cout << "Second Member: " << it->second << std::endl;
    	}
    }
    
    


 




STL关联容器:简单的标准库类型-pair类型
代码来源:C++ Primer 4
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>
#include <vector>
using  namespace  std;
 
int  main()
{
     pair<string, string> anon;     // 包含两个字符串
     pair<string,  int > word_count;  // 包含字符串和整数
     pair<string, vector< int > > line;  // 包含字符串和一个int容器
 
     pair<string, string> author( "James" "Joyce" );  // 定义成员时初始化
     cout << author.first <<  " - "  << author.second << endl;
 
     string firstBook;              // 使用 . 访问和测试pair数据成员
     if  (author.first ==  "James"  && author.second ==  "Joyce" ) {
         firstBook =  "Stephen Hero" ;
         cout << firstBook << endl;
     }
 
     typedef  pair<string, string> Author;  // 简化声明一个作者pair类型
     Author proust( "Marcel" "Proust" );
     Author Joyce( "James" "Joyce" );
 
     pair<string, string> next_auth;
     string first, last;
     while  (cin >> first >> last) {
         // 使用make_pair函数生成一个新pair对象
         next_auth = make_pair(first, last);
         // 使用make_pair函数,等价于下面这句
         next_auth = pair<string, string> (first, last);
 
         cout << next_auth.first <<  " - "  << next_auth.second << endl;
         if  (next_auth.first == next_auth.second)
             break // 输入两个相等,退出循环
     }
 
     cout <<   "因为pair的数据成员是共有的,因而可以直接读取输入"  << endl;
     while  (cin >> next_auth.first >> next_auth.second) {
 
         cout << next_auth.first <<  " - "  << next_auth.second << endl;
         if  (next_auth.first == next_auth.second)
             break ;
     }
 
     return  0;
}
 
 
 


insert()函数:
    iterator insert( iterator pos, const pair<KEY_TYPE,VALUE_TYPE> &val );
    void insert( input_iterator start, input_iterator end );
    pair<iterator, bool> insert( const pair<KEY_TYPE,VALUE_TYPE> &val );

插入val到pos的后面,然后返回一个指向这个元素的迭代器。
插入start到end的元素到map中。
只有在val不存在时插入val。返回值是一个指向被插入元素的迭代器和一个描述是否插入的bool值。


C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <map>
using  namespace  std;
 
int  main()
{
     map< char int > mymap;
     map< char int >::iterator it;
     pair<map< char int >::iterator,  bool > ret;  // 包含一个迭代器和一个bool值的的pair对象
 
     // 第一个insert函数版本 (single parameter): 单参数
     // 只有在val不存在时插入val。返回值是一个指向被插入元素的迭代器和一个描述是否插入的bool值。
     mymap.insert(pair< char int >( 'a' , 100));
     mymap.insert(make_pair( 'z' , 200));    // 使用make_pair函数简化插入参数
     typedef  map< char int >::value_type valType;
     mymap.insert(valType( 't' , 200));      // 或者使用 typedef 简化,提高程序的可读性
     
     ret = mymap.insert(pair< char int >( 'z' , 500));  // 因为已经存在,不能插入
     if  (ret.second ==  false ) {
         cout <<  "元素'z'已经存在," ;
         cout <<  " 他的值是 "  << ret.first->second << endl;  // ret.firs是迭代器指向map中具有相应键的元素
     }
 
     // 第二个insert函数版本 (with hint position): 插入val到pos的后面,然后返回一个指向这个元素的迭代器
     it = mymap.begin();
     mymap.insert(it, pair< char int >( 'b' , 300));  // 最大效率的插入,'b'直接插入在'a' 后面
     mymap.insert(it, pair< char int >( 'c' , 400));  // 没有最大效率的插入,'c'以'a'位置搜索存储的位置
 
     // 第三个insert函数版本 (range insertion): 范围插入 start到end的元素到map中
     map< char int > anothermap;
     anothermap.insert(mymap.begin(), mymap.find( 'c' ));  // find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。
 
     // 遍历容器查看内容:
     cout <<  "mymap 包含内容:\n" ;
     for  (it = mymap.begin() ; it != mymap.end(); it++)
         cout << (*it).first <<  " => "  << (*it).second << endl;
 
     cout <<  "anothermap 包含内容:\n" ;
     for  (it = anothermap.begin() ; it != anothermap.end(); it++)
         cout << it->first <<  " => "  << it->second << endl;
 
     return  0;
}



输出结果:
元素'z'已经存在, 他的值是 200
mymap 包含内容:
a => 100
b => 300
c => 400
t => 200
z => 200
anothermap 包含内容:
a => 100
b => 300
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值