# std::data

< cpp‎ | iterator

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

返回指向含有范围元素的内存块的指针。

1,2) 返回 c.data()
3) 返回 array
4) 返回 il.begin()

### 参数

c | - | 有 data() 方法的容器或视图
array | - | 任意类型的数组
il | - | initializer_list

### 返回值

指向含有容器范围的内存块的指针。

### 异常

1) 可能抛出实现定义的异常。

### 注解

需要对 std::initializer_list 的重载，因为它无成员函数 `data` 。

### 可能的实现

版本一
    template <class C>
    constexpr auto data(C& c) -> decltype(c.data())
    {
        return c.data();
    }
版本二
    template <class C>
    constexpr auto data(const C& c) -> decltype(c.data())
    {
        return c.data();
    }
版本三
    template <class T, std::size_t N>
    constexpr T* data(T (&array)[N]) noexcept
    {
        return array;
    }
版本四
    template <class E>
    constexpr const E* data(std::initializer_list<E> il) noexcept
    {
        return il.begin();
    }

### 示例

    #include <string>
    #include <cstring>
    #include <iostream>

    int main()
    {
        std::string s {"Hello world!\n"};

        char a[20]; // C-style 风格字符串的存储
        std::strcpy(a, std::data(s));
        // C++11 起 [s.data(), s.data() + s.size()] 保证为 NTBS

        std::cout << a;
    }

输出：

    Hello world!

### 参阅

ranges::data (C++20) | 获得指向连续范围的起始的指针 (定制点对象)
ranges::cdata (C++20) | 获得指向只读连续范围的起始的指针 (定制点对象)