# std::begin, std::cbegin

< cpp‎ | iterator

定义于头文件 `<array>` |  |
定义于头文件 `<deque>` |  |
定义于头文件 `<forward_list>` |  |
定义于头文件 `<iterator>` |  |
定义于头文件 `<list>` |  |
定义于头文件 `<map>` |  |
定义于头文件 `<regex>` |  |
定义于头文件 `<set>` |  |
定义于头文件 `<span>` |  | (C++20 起)
定义于头文件 `<string>` |  |
定义于头文件 `<string_view>` |  | (C++17 起)
定义于头文件 `<unordered_map>` |  |
定义于头文件 `<unordered_set>` |  |
定义于头文件 `<vector>` |  |
| (1) |
template< class C > auto begin( C& c ) -> decltype(c.begin()); |  | (C++11 起) (C++17 前)
template< class C > constexpr auto begin( C& c ) -> decltype(c.begin()); |  | (C++17 起)
| (1) |
template< class C > auto begin( const C& c ) -> decltype(c.begin()); |  | (C++11 起) (C++17 前)
template< class C > constexpr auto begin( const C& c ) -> decltype(c.begin()); |  | (C++17 起)
| (2) |
template< class T, std::size_t N > T* begin( T (&array)[N] ); |  | (C++11 起) (C++14 前)
template< class T, std::size_t N > constexpr T* begin( T (&array)[N] ) noexcept; |  | (C++14 起)
template< class C > constexpr auto cbegin( const C& c ) noexcept(/* see below */) -> decltype(std::begin(c)); | (3) | (C++14 起)

返回指向给定范围起始的迭代器。

1) 准确返回 c.begin() ，典型地是指向 `c` 所代表的序列起始的迭代器。若 `C` 是标准容器 (Container) ，则在 `c` 不是 const 限定时返回 C::iterator ，否则返回 C::const_iterator 。
2) 返回指向 `array` 起始的指针。
3) 准确返回 std::begin(c) ，这里 `c` 始终被视为 const 限定。若 `C` 是标准容器 (Container) ，则始终返回 C::const_iterator 。

### 参数

c | - | 带 `begin` 成员函数的容器或视图
array | - | 任意类型的数组

### 返回值

指向范围起始的迭代器

### 异常

3)
`noexcept` 说明：
noexcept(noexcept(std::begin(c)))

### 重载

可以为不暴露适合的 `begin()` 成员函数的类或枚举提供 `begin` 的自定义重载，从而能迭代它。标准库已提供下列重载：

std::begin(std::initializer_list) (C++11) | 特化 std::begin (函数模板)
std::begin(std::valarray) (C++11) | 特化的 std::begin (函数模板)
begin(std::filesystem::directory_iterator)end(std::filesystem::directory_iterator) | 基于范围的 for 循环支持 (函数)
begin(std::filesystem::recursive_directory_iterator)end(std::filesystem::recursive_directory_iterator) | 基于范围的 for 循环支持 (函数)

同 `swap` 的使用（于可交换 (Swappable) 描述）， `begin` 函数在泛型语境中的使用等价于 using std::begin; begin(arg);，这允许 ADL 为用户定义类型所选的重载和出现于同一重载集的标准库函数模板。

    template<typename Container, typename Function>
    void for_each(Container&& cont, Function f) {
        using std::begin;
        auto it = begin(cont);
        using std::end;
        auto end_it = end(cont);
        while (it != end_it) {
            f(*it);
            ++it;
        }
    }

实参依赖查找所找到的 `begin` 重载能用于定制 std::ranges::begin、 std::ranges::cbegin 及其他依赖于 std::ranges::begin 的定制点对象的行为。 | (C++20 起)

### 注解

(1,3) 准确地反映 C::begin() 的行为。若该成员函数无合理的实现，则它们的效果可能令人惊异。

`std::cbegin` 是为统一成员与非成员范围访问引入的。参阅 LWG 问题 2128 。

若 `C` 是浅 const 的视图，则 `std::cbegin` 可能返回可变的迭代器。某些用户不期待这种行为。参阅 P2276 与 P2278 。

### 示例

    #include <iostream>
    #include <vector>
    #include <iterator>

    int main()
    {
        std::vector<int> v = { 3, 1, 4 };
        auto vi = std::begin(v);
        std::cout << *vi << '\n';

        int a[] = { -5, 10, 15 };
        auto ai = std::begin(a);
        std::cout << *ai << '\n';
    }

输出：

    3
    -5

### 参阅

end cend (C++11)(C++14) | 返回指向容器或数组结尾的迭代器 (函数模板)
ranges::begin (C++20) | 返回指向范围起始的迭代器 (定制点对象)
ranges::cbegin (C++20) | 返回指向只读范围起始的迭代器 (定制点对象)