Unverified Commit d087455c authored by Sshwy's avatar Sshwy Committed by GitHub
Browse files

Merge pull request #1778 from StudyingFather/master

将 C++ 新特性中的 array 部分内容合并到 STL 中
parents dc15fce7 8c00e56f
Loading
Loading
Loading
Loading
+48 −3
Original line number Diff line number Diff line
author: MingqiHuang, Xeonacid, greyqz, i-Yirannn
author: MingqiHuang, Xeonacid, greyqz, i-Yirannn, ChenZ01

##  `vector` 

@@ -167,9 +167,54 @@ vector 提供了如下几种 [迭代器](./iterator.md)

 `array` 实际上是 STL 对数组的封装。它相比 `vector` 牺牲了动态扩容的特性,但是换来了与原生数组几乎一致的性能(在开满优化的前提下)。因此如果能使用 C++11 特性的情况下,能够使用原生数组的地方几乎都可以直接把定长数组都换成 `array` ,而动态分配的数组可以替换为 `vector`

###  `array` 的使用方法
### 成员函数

 `array` 的使用方法与 `vector` 高度相似,仅有声明方式与 `vector` 不同,以及没有元素增删的能力(如 `push_back` )。这里只给出一段例子,详细内容 [请参见 C++ 文档](https://zh.cppreference.com/w/cpp/container/array)
#### 隐式定义的成员函数

| 函数            | 作用                                  |
| ------------- | ----------------------------------- |
|  `operator=`  | 以来自另一 `array` 的每个元素重写 `array` 的对应元素 |

#### 元素访问

| 函数             | 作用                    |
| -------------- | --------------------- |
|  `at`          | 访问指定的元素,同时进行越界检查      |
|  `operator[]`  | 访问指定的元素, **不** 进行越界检查 |
|  `front`       | 访问第一个元素               |
|  `back`        | 访问最后一个元素              |
|  `data`        | 返回指向内存中数组第一个元素的指针     |

 `at` 若遇 `pos >= size()` 的情况会抛出 `std::out_of_range`

#### 容量

| 函数           | 作用          |
| ------------ | ----------- |
|  `empty`     | 检查容器是否为空    |
|  `size`      | 返回容纳的元素数    |
|  `max_size`  | 返回可容纳的最大元素数 |

由于每个 `array` 都是固定大小容器, `size()` 返回的值等于 `max_size()` 返回的值。

### 操作

| 函数       | 作用       |
| -------- | -------- |
|  `fill`  | 以指定值填充容器 |
|  `swap`  | 交换内容     |

 **注意,交换两个 `array` 是 $\Theta(\text{size})$ 的,而非与常规 STL 容器一样为 $O(1)$ 。** 

### 非成员函数

| 函数              | 作用                  |
| --------------- | ------------------- |
|  `operator==` 等 | 按照字典序比较 `array` 中的值 |
|  `std::get`     | 访问 `array` 的一个元素    |
|  `std::swap`    | 特化的 `std::swap` 算法  |

下面是一个 `array` 的使用示例:

```cpp
// 1. 创建空array,长度为3; 常数复杂度
+0 −82
Original line number Diff line number Diff line
@@ -261,88 +261,6 @@ std::swap(tupA, tupB);
std::cout << std::get<1>(tupA) << std::endl;
```

## std::array

 `std::array` 定义于头文件 `<array>` ,是封装固定大小数组的容器,其语义等同于保有一个 C 风格数组作为其唯一非静态数据成员的结构体。来看一个例子

```cpp
#include <algorithm>
#include <array>
#include <iostream>

int main() {
  std::array<int, 5> a = {1, 9, 2, 6, 0};
  std::array<int, 5> b = a;
  std::sort(a.begin(), a.end());
  for (auto i : a) std::cout << i << " ";
  std::cout << std::endl << a[0] << " " << a.front() << std::endl;
  std::cout << (a != b) << std::endl;
}
```

### 成员函数

#### 隐式定义的成员函数

| 函数            | 作用                                  |
| ------------- | ----------------------------------- |
|  `operator=`  | 以来自另一 `array` 的每个元素重写 `array` 的对应元素 |

#### 元素访问

| 函数             | 作用                    |
| -------------- | --------------------- |
|  `at`          | 访问指定的元素,同时进行越界检查      |
|  `operator[]`  | 访问指定的元素, **不** 进行越界检查 |
|  `front`       | 访问第一个元素               |
|  `back`        | 访问最后一个元素              |
|  `data`        | 返回指向内存中数组第一个元素的指针     |

 `at` 若遇 `pos >= size()` 的情况会抛出 `std::out_of_range`

#### 容量

| 函数           | 作用          |
| ------------ | ----------- |
|  `empty`     | 检查容器是否为空    |
|  `size`      | 返回容纳的元素数    |
|  `max_size`  | 返回可容纳的最大元素数 |

由于每个 `array` 都是固定大小容器, `size()` 返回的值等于 `max_size()` 返回的值。

### 操作

| 函数       | 作用       |
| -------- | -------- |
|  `fill`  | 以指定值填充容器 |
|  `swap`  | 交换内容     |

 **注意,交换两个 `array` 是 $\Theta(\text{size})$ 的,而非与常规 STL 容器一样为 $O(1)$ 。** 

### 非成员函数

| 函数              | 作用                  |
| --------------- | ------------------- |
|  `operator==` 等 | 按照字典序比较 `array` 中的值 |
|  `std::get`     | 访问 `array` 的一个元素    |
|  `std::swap`    | 特化的 `std::swap` 算法  |

例子

```cpp
#include <array>
#include <iostream>

int main() {
  std::array<int, 5> a;
  a[0] = 1;
  std::cout << a.size() << " " << a.max_size() << std::endl;
  a.fill(0x7f7f7f7f);
  std::cout << a.front() << " " << a.at(4) << std::endl;
  return 0;
}
```

## std::function

类模板 `std::function` 是通用多态函数封装器,定义于头文件 `<functional>``std::function` 的实例能存储、复制及调用任何可调用(_Callable_)目标——函数、Lambda 表达式或其他函数对象,还有指向成员函数指针和指向数据成员指针。