# range-based for 循环

URL: https://caijiao.org/cpp/stl/range-for
Source: docs/cpp/stl/range-for.md
Description: 本节介绍 C++ 中的 range-based for 循环，简化了遍历容器的过程，使代码更加简洁易懂。

在 C++11 中，`range-based for` 循环提供了一种简洁的方式来遍历容器或数组。与传统的 `for` 循环相比，`range-based for` 循环使得代码更简洁，减少了出错的机会，特别是在遍历容器时。

## range-based for 循环语法

```cpp
for (declaration : container) {
    // 访问 container 中的每个元素
}
````

* `declaration`：表示每个元素的类型，通常是引用或值类型。
* `container`：可以是数组、容器（如 `vector`、`list`、`map` 等）或其他支持迭代的对象。

## 示例：遍历数组

```cpp
#include <iostream>

using namespace std;

int main() {
    int arr[] = {1, 2, 3, 4, 5};

    // 使用 range-based for 循环遍历数组
    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}
```

在此例中，`num` 将依次获取数组 `arr` 中的每个元素，并打印出来。

## 示例：遍历 `vector`

```cpp
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v = {10, 20, 30, 40, 50};

    // 使用 range-based for 循环遍历 vector
    for (int num : v) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}
```

此示例中，`v` 是一个 `vector`，通过 `range-based for` 循环遍历其中的每个元素。

## 引用与值

默认情况下，`range-based for` 循环会复制元素。如果需要修改容器中的元素，可以使用引用类型。

### 示例：使用引用修改容器中的元素

```cpp
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5};

    // 使用引用来修改元素
    for (int& num : v) {
        num *= 2;  // 将每个元素乘以 2
    }

    // 输出修改后的 vector
    for (int num : v) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}
```

在此例中，通过引用 `int& num` 来修改 `v` 中的每个元素，使每个元素的值都翻倍。

## 常见错误

### 忘记引用类型

当你希望修改元素时，忘记加上引用类型会导致创建元素的副本，从而无法改变容器中的实际内容。

### 示例：没有引用的错误

```cpp
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5};

    // 错误：没有引用，不能修改原始元素
    for (int num : v) {
        num *= 2;  // 只是修改了 num，而不是 v 中的元素
    }

    for (int num : v) {
        cout << num << " ";
    }
    cout << endl;  // 输出仍然是 1 2 3 4 5

    return 0;
}
```

在此例中，由于没有使用引用，修改的是 `num` 的副本，容器 `v` 中的元素并没有变化。

## 总结

* `range-based for` 循环使得遍历容器或数组更加简洁。
* 默认情况下，元素会被复制。如果需要修改元素，使用引用。
* 使用 `range-based for` 循环时，避免忘记加引用类型，这样才能修改容器中的实际元素。

通过 `range-based for` 循环，C++ 代码可以变得更加简洁、清晰，减少了手动管理迭代器和循环变量的复杂度。
