Team LiB
Previous Section Next Section

10.1. Preliminaries: the pair Type

10.1. 引言:pair 类型

Before we look at the associative containers, we need to know about a simple companion library type named pair, which is defined in the utility header.

在开始介绍关联容器之前,必须先了解一种与之相关的简单的标准库类型——pair表 10.2),该类型在 utility 头文件中定义。

Table 10.2. Operations on pairs
表 10.2 pairs 类型提供的操作

pair<T1, T2> p1;

Create an empty pair with two elements of types T1 and T2. The elements are value-initialized (Section 3.3.1, p. 92).

创建一个空的 pair 对象,它的两个元素分别是 T1T2 类型,采用值初始化(第 3.3.1 节

pair<T1, T2> p1(v1, v2);

 
 

Create a pair with types T1 and T2 initializing the first member from v1 and the second from v2.

创建一个 pair 对象,它的两个元素分别是 T1T2 ,其中 first 成员初始化为 v1,而 second 成员初始化为 v2

make_pair(v1, v2)

Creates a new pair from the values v1 and v2. The type of the pair is inferred from the types of v1 and v2.

v1v2 值创建一个新 pair 对象,其元素类型分别是 v1v2 的类型

p1 < p2

Less than between two pair objects. Less than is defined as dictionary ordering: Returns true if p1.first < p2.first or if !(p2.first < p1.first) && p1.second < p2.second.

两个 pair 对象之间的小于运算,其定义遵循字典次序:如果 p1.first < p2.first 或者 !(p2.first < p1.first) && p1.second < p2.second,则返回 true

p1 == p2

Two pairs are equal if their first and second members are respectively equal. Uses the underlying element == operator.

如果两个 pair 对象的 firstsecond 成员依次相等,则这两个对象相等。该运算使用其元素的 == 操作符

p.first

Returns the (public) data member of p named first.

返回 p 中名为 first 的(公有)数据成员

p.second

Returns the (public) data member of p named second.

返回 p 的名为 second 的(公有)数据成员


Creating and Initializing pairs

pair 的创建和初始化

A pair holds two data values. Like the containers, pair is a template type. Unlike the containers we've seen so far, we must supply two type names when we create a pair: A pair holds two data members, each of which has the corresponding named type. There is no requirement that the two types be the same.

pair 包含两个数据值。与容器一样,pair 也是一种模板类型。但又与之前介绍的容器不同,在创建 pair 对象时,必须提供两个类型名:pair 对象所包含的两个数据成员各自对应的类型名字,这两个类型必相同。

     pair<string, string> anon;       // holds two strings
     pair<string, int> word_count;    // holds a string and an int
     pair<string, vector<int> > line; // holds string and vector<int>

When we create pair objects with no initializer, the default constructor value-initializes the members. Thus, anon is a pair of two empty strings, and line holds an empty string and an empty vector. The int value in word_count gets the value 0 and the string member is initialized to the empty string.

如果在创建 pair 对象时不提供初始化式,则调用默认构造函数对其成员采用值初始化。于是,anon 是包含两空 string 类型成员的 pair 对象,line 则存储一个空的 string 类型对象和一个空的vector 类型对象。word_count 中的 int 成员获得 0 值,而 string 成员则初始化为空 string 对象。

We can also provide initializers for each member:

当然,也可在定义时为每个成员提供初始化式:

     pair<string, string> author("James", "Joyce");

creates a pair named author, in which each member has type string. The object named author is initialized to hold two strings with the values "James" and "Joyce".

创建一个名为 authorpair 对象,它的两个成员都是 string 类型,分别初始化为字符串 "James""Joyce"

The pair type can be unwieldy to type, so when we wish to define a number of objects of the same pair type, it is convenient to use a typedef (Section 2.6, p. 61):

pair 类型的使用相当繁琐,因此,如果需要定义多个相同的 pair 类型对象,可考虑利用 typedef 简化其声明:

     typedef pair<string, string> Author;
     Author proust("Marcel", "Proust");
     Author joyce("James", "Joyce");

Operations on pairs

pairs 对象的操作

Unlike other library types, the pair class gives us direct access to its data members: Its members are public. These members are named first and second, respectively. We can access them using the normal dot operator (Section 1.5.2, p. 25) member access notation:

与其他标准库类型不同,对于 pair 类,可以直接访问其数据成员:其成员都是仅有的,分别命名为 firstsecond。只需使用普通的点操作符——成员访问标志即可访问其成员:

     string firstBook;
     // access and test the data members of the pair
     if (author.first == "James" && author.second == "Joyce")
         firstBook = "Stephen Hero";

The library defines only a limited number of operations on pairs, which are listed in Table 10.2 on the preceding page.

标准库只为 pair 类型定义了表 10.2 所列出的数量有限的操作。

Generating a New pair

生成新的 pair 对象

In addition to the constructors, the library defines the make_pair function, which generates a new pair from its two arguments. We might use this function to make a new pair to assign to an existing pair:

除了构造函数,标准库还定义了一个 make_pair 函数,由传递给它的两个实参生成一个新的 pair 对象。可如下使用该函数创建新的 pair 对象,并赋给已存在的 pair 对象:

     pair<string, string> next_auth;
     string first, last;
     while (cin >> first >> last) {
         // generate a pair from first and last
         next_auth = make_pair(first, last);
         // process next_auth...
     }

This loop processes a sequence of authors. The call to make_pair generates a new pair from the names read in the while condition. It is equivalent to the somewhat more complicated

这个循环处理一系列的作者信息:在 while 循环条件中读入的作者名字作为实参,调用 make_pair 函数生成一个新的 pair 对象。此操作等价于下面更复杂的操作:

     // use pair constructor to make first and last into a pair
     next_auth = pair<string, string>(first, last);

Because the data members of pair are public, we could read the inputeven more directly as

由于 pair 的数据成员是公有的,因而可如下直接地读取输入:

     pair<string, string> next_auth;
     // read directly into the members of next_auth
     while (cin >> next_auth.first >> next_auth.second) {
         // process next_auth...
     }

Exercises Section 10.1

Exercise 10.1:

Write a program to read a sequence of strings and ints, storing each into a pair. Store the pairs in a vector.

编写程序读入一系列 stringint 型数据,将每一组存储在一个 pair 对象中,然后将这些 pair 对象存储在 vector 容器里。

Exercise 10.2:

There are at least three ways to create the pairs in the program for the previous exercise. Write three versions of the program creating the pairs in each way. Indicate which form you think is easier to write and understand and why.

在前一题中,至少可使用三种方法创建 pair 对象。编写三个版本的程序,分别采用不同的方法来创建 pair 对象。你认为哪一种方法更易于编写和理解,为什么?


Team LiB
Previous Section Next Section