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,这符合大多数应用的逻辑。当然,也可以通过重载这几个运算符来重新指定自己的比较逻辑。
- 例子程序:
-
- // map/pair-test.cpp - Show basic use of pair.
- // 2004-02-29 - Fred Swartz - Rodenbach
- #include <utility>
- #include <iostream>
- #include <string>
- #include <map>
- using namespace std;
- int main() {
- //-- Declare a pair variable.
- pair<string, int> pr1;
- //-- Declare and initialize with constructor.
- pair<string, int> pr2("heaven", 7);
- cout << pr2.first << "=" << pr2.second << endl;
- // Prints heaven=7
- //-- Declare and initialize pair pointer.
- pair<string, int>* prp = new pair<string, int>("yards", 9);
- cout << prp->first << "=" << prp->second << endl;
- // Prints yards=9
- //-- Declare map and assign value to keys.
- map<string, string> engGerDict;
- engGerDict["shoe"] = "Schuh";
- engGerDict["head"] = "Kopf";
- //-- Iterate over map. Iterator value is a key-value pair.
- // Iteration in map is in sorted order.
- map<string, string>::const_iterator it;
- for (it=engGerDict.begin(); it != engGerDict.end(); ++it) {
- cout << it->first << "=" << it->second << endl;
- }
- // Prints head=kopf
- // shoe=Schuh
- system("PAUSE");
- return 0;
- }
-
除了直接定义一个pair对象外,如果需要即时生成一个pair对象,也可以调用在<utility>中定义的一个模板函数:make_pair。make_pair需要两个参数,分别为元素对的首元素和尾元素。
- 例子程序:
-
- // mkpair.cpp
- // compile with: /EHsc
- // Illustrates how to use the make_pair function.
- //
- // Functions: make_pair - creates an object pair containing two data
- // elements of any type.
- ========make_pair
- #include <utility>
- #include <iostream>
- using namespace std;
- /* STL pair data type containing int and float
- */
- typedef struct pair<int,float> PAIR_IF;
- int main(void)
- {
- PAIR_IF pair1=make_pair(18,3.14f);
- cout << pair1.first << " " << pair1.second << endl;
- pair1.first=10;
- pair1.second=1.0f;
- cout << pair1.first << " " << pair1.second << endl;
- }
// 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; } }
![](http://hi.csdn.net/attachment/201112/11/3362235_1323605959GcHV.png)
STL关联容器:简单的标准库类型-pair类型
代码来源:C++ Primer 4
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;
}
|
![](http://hi.csdn.net/attachment/201112/11/3362235_1323612234OHEk.png)
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值。
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