STL:std::array 和 基本数组类型array 浅谈一二三

news2025/2/7 13:50:18

一、优缺点比较

在C++中,std::array是标准库提供的数组容器,相比于基础数据类型的数组,它具有以下优点和缺点:

优点:

    1. 安全性:std::array提供了边界检查,可以避免数组越界访问的问题。
    1. 可以作为函数参数:std::array可以作为函数的参数和返回值,而基础数据类型的数组不能直接作为函数参数传递。
    1. 支持STL算法:std::array可以直接使用STL算法,如std::sortstd::find等,而基础数据类型的数组需要手动实现这些算法。

缺点:

    1. 大小固定:std::array的大小在编译时就需要确定,无法动态改变大小,而基础数据类型的数组可以使用newdelete动态分配和释放内存。
    1. 初始化复杂:相比于基础数据类型的数组,std::array的初始化语法可能更加繁琐。std::array 不支持参数列表的初始化形式。

总的来说,std::array相比于基础数据类型的数组更加安全和方便,但在某些情况下可能会有一些额外的开销和限制。

二、代码示例

#include <any>
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <array>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
using namespace std;

#define NOUSE(x) (void)x;

// test array
template <typename _Ty,size_t N>
void array_test_func(std::array<_Ty,N>& arr)
{
    /// 通过迭代器遍历
    auto traver_1 = [&](){
#if 0
        auto iter = arr.begin();
        for(;iter != arr.end();++iter)
            cout << *iter << " ";
#else
        std::copy(arr.cbegin(), arr.cend(), std::ostream_iterator<_Ty>(std::cout, " "));
#endif
        cout << endl;
    };
    traver_1();

    cout << "back  ==> " << arr.back() << endl;     // 首字符
    cout << "front ==> " << arr.front() << endl;    // 尾字符

    size_t n =  arr.size(); // 长度
    /// 通过数组指针遍历
    auto traver_2 = [&](){
        _Ty* dptr = arr.data(); // 首地址

        for(size_t i = 0; i < n ;++i){
            cout << *(dptr+i) << " ";
        }
        cout << endl;
    };
    traver_2();


    /// 通过下标遍历
    auto traver_3 = [&](){
       for(size_t i = 0; i < n;++i){
           cout << arr.at(i) << " ";
       }
       cout << endl;
    };
    traver_3();
}

int main(int argc, char *argv[])
{
    NOUSE(argc);
    NOUSE(argv);

    std::array<int,3> arr = {2,6,4};
    array_test_func<int,3>(arr);

    // array_test_func<int,3>({2,4,6}); // error : 不支持 initializer_list

    std::sort(arr.begin(),arr.end()); // 支持STL算法
    array_test_func<int,3>(arr);

    return 0;
}

三、源码赏析

// array standard header

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#pragma once
#ifndef _ARRAY_
#define _ARRAY_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#include <xutility>

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

_STD_BEGIN
#if _ITERATOR_DEBUG_LEVEL != 0
struct _Iterator_base12_compatible { // TRANSITION, for binary compatibility
    _Container_proxy* _Myproxy{};
    _Iterator_base12* _Mynextiter{};
};
#endif // _ITERATOR_DEBUG_LEVEL != 0

 定于数组的const迭代器
template <class _Ty, size_t _Size>
class _Array_const_iterator
#if _ITERATOR_DEBUG_LEVEL != 0
    : private _Iterator_base12_compatible
#endif // _ITERATOR_DEBUG_LEVEL != 0
{
public:
#ifdef __cpp_lib_concepts
    using iterator_concept = contiguous_iterator_tag;
#endif // __cpp_lib_concepts
    using iterator_category = random_access_iterator_tag;
    using value_type        = _Ty;
    using difference_type   = ptrdiff_t;
    using pointer           = const _Ty*;
    using reference         = const _Ty&;

    enum { _EEN_SIZE = _Size }; // helper for expression evaluator

#if _ITERATOR_DEBUG_LEVEL == 0
    _CONSTEXPR17 _Array_const_iterator() noexcept : _Ptr() {}

    _CONSTEXPR17 explicit _Array_const_iterator(pointer _Parg, size_t _Off = 0) noexcept : _Ptr(_Parg + _Off) {}

    _NODISCARD _CONSTEXPR17 reference operator*() const noexcept {
        return *_Ptr;
    }

    _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept {
        return _Ptr;
    }

    _CONSTEXPR17 _Array_const_iterator& operator++() noexcept {
        ++_Ptr;
        return *this;
    }

    _CONSTEXPR17 _Array_const_iterator operator++(int) noexcept {
        _Array_const_iterator _Tmp = *this;
        ++_Ptr;
        return _Tmp;
    }

    _CONSTEXPR17 _Array_const_iterator& operator--() noexcept {
        --_Ptr;
        return *this;
    }

    _CONSTEXPR17 _Array_const_iterator operator--(int) noexcept {
        _Array_const_iterator _Tmp = *this;
        --_Ptr;
        return _Tmp;
    }

    _CONSTEXPR17 _Array_const_iterator& operator+=(const ptrdiff_t _Off) noexcept {
        _Ptr += _Off;
        return *this;
    }

    _NODISCARD _CONSTEXPR17 _Array_const_iterator operator+(const ptrdiff_t _Off) const noexcept {
        _Array_const_iterator _Tmp = *this;
        return _Tmp += _Off;
    }

    _CONSTEXPR17 _Array_const_iterator& operator-=(const ptrdiff_t _Off) noexcept {
        _Ptr -= _Off;
        return *this;
    }

    _NODISCARD _CONSTEXPR17 _Array_const_iterator operator-(const ptrdiff_t _Off) const noexcept {
        _Array_const_iterator _Tmp = *this;
        return _Tmp -= _Off;
    }

    _NODISCARD _CONSTEXPR17 ptrdiff_t operator-(const _Array_const_iterator& _Right) const noexcept {
        return _Ptr - _Right._Ptr;
    }

    _NODISCARD _CONSTEXPR17 reference operator[](const ptrdiff_t _Off) const noexcept {
        return _Ptr[_Off];
    }

    _NODISCARD _CONSTEXPR17 bool operator==(const _Array_const_iterator& _Right) const noexcept {
        return _Ptr == _Right._Ptr;
    }

#if _HAS_CXX20
    _NODISCARD constexpr strong_ordering operator<=>(const _Array_const_iterator& _Right) const noexcept {
        return _Ptr <=> _Right._Ptr;
    }
#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv
    _NODISCARD _CONSTEXPR17 bool operator!=(const _Array_const_iterator& _Right) const noexcept {
        return !(*this == _Right);
    }

    _NODISCARD _CONSTEXPR17 bool operator<(const _Array_const_iterator& _Right) const noexcept {
        return _Ptr < _Right._Ptr;
    }

    _NODISCARD _CONSTEXPR17 bool operator>(const _Array_const_iterator& _Right) const noexcept {
        return _Right < *this;
    }

    _NODISCARD _CONSTEXPR17 bool operator<=(const _Array_const_iterator& _Right) const noexcept {
        return !(_Right < *this);
    }

    _NODISCARD _CONSTEXPR17 bool operator>=(const _Array_const_iterator& _Right) const noexcept {
        return !(*this < _Right);
    }
#endif // !_HAS_CXX20

    using _Prevent_inheriting_unwrap = _Array_const_iterator;

    _NODISCARD constexpr pointer _Unwrapped() const noexcept {
        return _Ptr;
    }

    static constexpr bool _Unwrap_when_unverified = true;

    constexpr void _Seek_to(pointer _It) noexcept {
        _Ptr = _It;
    }

private:
    pointer _Ptr; // beginning of array

#else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 / _ITERATOR_DEBUG_LEVEL != 0 vvv
    _CONSTEXPR17 _Array_const_iterator() noexcept : _Ptr(), _Idx(0) {}

    _CONSTEXPR17 explicit _Array_const_iterator(pointer _Parg, size_t _Off = 0) noexcept : _Ptr(_Parg), _Idx(_Off) {}

    _NODISCARD _CONSTEXPR17 reference operator*() const noexcept {
        return *operator->();
    }

    _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept {
        _STL_VERIFY(_Ptr, "cannot dereference value-initialized array iterator");
        _STL_VERIFY(_Idx < _Size, "cannot dereference out of range array iterator");
        return _Ptr + _Idx;
    }

    _CONSTEXPR17 _Array_const_iterator& operator++() noexcept {
        _STL_VERIFY(_Ptr, "cannot increment value-initialized array iterator");
        _STL_VERIFY(_Idx < _Size, "cannot increment array iterator past end");
        ++_Idx;
        return *this;
    }

    _CONSTEXPR17 _Array_const_iterator operator++(int) noexcept {
        _Array_const_iterator _Tmp = *this;
        ++*this;
        return _Tmp;
    }

    _CONSTEXPR17 _Array_const_iterator& operator--() noexcept {
        _STL_VERIFY(_Ptr, "cannot decrement value-initialized array iterator");
        _STL_VERIFY(_Idx != 0, "cannot decrement array iterator before begin");
        --_Idx;
        return *this;
    }

    _CONSTEXPR17 _Array_const_iterator operator--(int) noexcept {
        _Array_const_iterator _Tmp = *this;
        --*this;
        return _Tmp;
    }

    constexpr void _Verify_offset(const ptrdiff_t _Off) const noexcept {
        if (_Off != 0) {
            _STL_VERIFY(_Ptr, "cannot seek value-initialized array iterator");
        }

        if (_Off < 0) {
            _STL_VERIFY(_Idx >= size_t{0} - static_cast<size_t>(_Off), "cannot seek array iterator before begin");
        }

        if (_Off > 0) {
            _STL_VERIFY(_Size - _Idx >= static_cast<size_t>(_Off), "cannot seek array iterator after end");
        }
    }

    _CONSTEXPR17 _Array_const_iterator& operator+=(const ptrdiff_t _Off) noexcept {
        _Verify_offset(_Off);
        _Idx += static_cast<size_t>(_Off);
        return *this;
    }

    _NODISCARD _CONSTEXPR17 _Array_const_iterator operator+(const ptrdiff_t _Off) const noexcept {
        _Array_const_iterator _Tmp = *this;
        return _Tmp += _Off;
    }

    _CONSTEXPR17 _Array_const_iterator& operator-=(const ptrdiff_t _Off) noexcept {
        return *this += -_Off;
    }

    _NODISCARD _CONSTEXPR17 _Array_const_iterator operator-(const ptrdiff_t _Off) const noexcept {
        _Array_const_iterator _Tmp = *this;
        return _Tmp -= _Off;
    }

    _NODISCARD _CONSTEXPR17 ptrdiff_t operator-(const _Array_const_iterator& _Right) const noexcept {
        _Compat(_Right);
        return static_cast<ptrdiff_t>(_Idx - _Right._Idx);
    }

    _NODISCARD _CONSTEXPR17 reference operator[](const ptrdiff_t _Off) const noexcept {
        return *(*this + _Off);
    }

    _NODISCARD _CONSTEXPR17 bool operator==(const _Array_const_iterator& _Right) const noexcept {
        _Compat(_Right);
        return _Idx == _Right._Idx;
    }

#if _HAS_CXX20
    _NODISCARD constexpr strong_ordering operator<=>(const _Array_const_iterator& _Right) const noexcept {
        _Compat(_Right);
        return _Idx <=> _Right._Idx;
    }
#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv
    _NODISCARD _CONSTEXPR17 bool operator!=(const _Array_const_iterator& _Right) const noexcept {
        return !(*this == _Right);
    }

    _NODISCARD _CONSTEXPR17 bool operator<(const _Array_const_iterator& _Right) const noexcept {
        _Compat(_Right);
        return _Idx < _Right._Idx;
    }

    _NODISCARD _CONSTEXPR17 bool operator>(const _Array_const_iterator& _Right) const noexcept {
        return _Right < *this;
    }

    _NODISCARD _CONSTEXPR17 bool operator<=(const _Array_const_iterator& _Right) const noexcept {
        return !(_Right < *this);
    }

    _NODISCARD _CONSTEXPR17 bool operator>=(const _Array_const_iterator& _Right) const noexcept {
        return !(*this < _Right);
    }
#endif // !_HAS_CXX20

    _CONSTEXPR17 void _Compat(const _Array_const_iterator& _Right) const noexcept { // test for compatible iterator pair
        _STL_VERIFY(_Ptr == _Right._Ptr, "array iterators incompatible");
    }

    using _Prevent_inheriting_unwrap = _Array_const_iterator;

    _NODISCARD constexpr pointer _Unwrapped() const noexcept {
        return _Ptr + _Idx;
    }

    constexpr void _Verify_with(const _Array_const_iterator& _Last) const noexcept {
        // note _Compat check inside operator<=
        _STL_VERIFY(*this <= _Last, "array iterator range transposed");
    }

    constexpr void _Seek_to(pointer _It) noexcept {
        _Idx = static_cast<size_t>(_It - _Ptr);
    }

private:
    pointer _Ptr; // beginning of array
    size_t _Idx; // offset into array
#endif // _ITERATOR_DEBUG_LEVEL == 0
};

#if _ITERATOR_DEBUG_LEVEL != 0
template <class _Ty, size_t _Size>
constexpr void _Verify_range(
    const _Array_const_iterator<_Ty, _Size>& _First, const _Array_const_iterator<_Ty, _Size>& _Last) noexcept {
    // TRANSITION, CUDA
    _First._Verify_with(_Last);
}
#endif // _ITERATOR_DEBUG_LEVEL != 0

/// 迭代器模板特化
template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR17 _Array_const_iterator<_Ty, _Size> operator+(
    const ptrdiff_t _Off, _Array_const_iterator<_Ty, _Size> _Next) noexcept {
    return _Next += _Off;
}

#if _HAS_CXX20
template <class _Ty, size_t _Size>
struct pointer_traits<_Array_const_iterator<_Ty, _Size>> {
    using pointer         = _Array_const_iterator<_Ty, _Size>;
    using element_type    = const _Ty;
    using difference_type = ptrdiff_t;

    _NODISCARD static constexpr element_type* to_address(const pointer _Iter) noexcept {
        return _Iter._Unwrapped();
    }
};
#endif // _HAS_CXX20

/// 定义子类:非常迭代器
template <class _Ty, size_t _Size>
class _Array_iterator : public _Array_const_iterator<_Ty, _Size> {
public:
    using _Mybase = _Array_const_iterator<_Ty, _Size>;

#ifdef __cpp_lib_concepts
    using iterator_concept = contiguous_iterator_tag;
#endif // __cpp_lib_concepts
    using iterator_category = random_access_iterator_tag;
    using value_type        = _Ty;
    using difference_type   = ptrdiff_t;
    using pointer           = _Ty*;
    using reference         = _Ty&;

    enum { _EEN_SIZE = _Size }; // helper for expression evaluator

    _CONSTEXPR17 _Array_iterator() noexcept {}

    _CONSTEXPR17 explicit _Array_iterator(pointer _Parg, size_t _Off = 0) noexcept : _Mybase(_Parg, _Off) {}

    _NODISCARD _CONSTEXPR17 reference operator*() const noexcept {
        return const_cast<reference>(_Mybase::operator*());
    }

    _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept {
        return const_cast<pointer>(_Mybase::operator->());  // 去常
    }

	// 前++ 重载
    _CONSTEXPR17 _Array_iterator& operator++() noexcept {
        _Mybase::operator++();
        return *this;
    }

	// 后加加重载
    _CONSTEXPR17 _Array_iterator operator++(int) noexcept {
        _Array_iterator _Tmp = *this;
        _Mybase::operator++();
        return _Tmp;
    }

	// 前减减重载 
    _CONSTEXPR17 _Array_iterator& operator--() noexcept {
        _Mybase::operator--();
        return *this;
    }

	// 后减减重载
    _CONSTEXPR17 _Array_iterator operator--(int) noexcept {
        _Array_iterator _Tmp = *this;
        _Mybase::operator--();
        return _Tmp;
    }

    _CONSTEXPR17 _Array_iterator& operator+=(const ptrdiff_t _Off) noexcept {
        _Mybase::operator+=(_Off);
        return *this;
    }

    _NODISCARD _CONSTEXPR17 _Array_iterator operator+(const ptrdiff_t _Off) const noexcept {
        _Array_iterator _Tmp = *this;
        return _Tmp += _Off;
    }

    _CONSTEXPR17 _Array_iterator& operator-=(const ptrdiff_t _Off) noexcept {
        _Mybase::operator-=(_Off);
        return *this;
    }

    using _Mybase::operator-;

    _NODISCARD _CONSTEXPR17 _Array_iterator operator-(const ptrdiff_t _Off) const noexcept {
        _Array_iterator _Tmp = *this;
        return _Tmp -= _Off;
    }

	// 下标操作符重载
    _NODISCARD _CONSTEXPR17 reference operator[](const ptrdiff_t _Off) const noexcept {
        return const_cast<reference>(_Mybase::operator[](_Off));
    }

    using _Prevent_inheriting_unwrap = _Array_iterator;

    _NODISCARD constexpr pointer _Unwrapped() const noexcept {
        return const_cast<pointer>(_Mybase::_Unwrapped());
    }
};

template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR17 _Array_iterator<_Ty, _Size> operator+(
    const ptrdiff_t _Off, _Array_iterator<_Ty, _Size> _Next) noexcept {
    return _Next += _Off;
}

#if _HAS_CXX20
template <class _Ty, size_t _Size>
struct pointer_traits<_Array_iterator<_Ty, _Size>> {
    using pointer         = _Array_iterator<_Ty, _Size>;
    using element_type    = _Ty;
    using difference_type = ptrdiff_t;

    _NODISCARD static constexpr element_type* to_address(const pointer _Iter) noexcept {
        return _Iter._Unwrapped();
    }
};
#endif // _HAS_CXX20


/// 定义数组模板
template <class _Ty, size_t _Size>
class array { // fixed size array of values
public:
    using value_type      = _Ty;
    using size_type       = size_t;
    using difference_type = ptrdiff_t;
    using pointer         = _Ty*;
    using const_pointer   = const _Ty*;
    using reference       = _Ty&;
    using const_reference = const _Ty&;

    using iterator       = _Array_iterator<_Ty, _Size>;
    using const_iterator = _Array_const_iterator<_Ty, _Size>;

    using reverse_iterator       = _STD reverse_iterator<iterator>;
    using const_reverse_iterator = _STD reverse_iterator<const_iterator>;

#if _HAS_TR1_NAMESPACE
    _DEPRECATE_TR1_NAMESPACE void assign(const _Ty& _Value) {
        _STD fill_n(_Elems, _Size, _Value);
    }
#endif // _HAS_TR1_NAMESPACE

    _CONSTEXPR20 void fill(const _Ty& _Value) {
        _STD fill_n(_Elems, _Size, _Value);
    }

    _CONSTEXPR20 void swap(array& _Other) noexcept(_Is_nothrow_swappable<_Ty>::value) {
        _Swap_ranges_unchecked(_Elems, _Elems + _Size, _Other._Elems);
    }

    _NODISCARD _CONSTEXPR17 iterator begin() noexcept {
        return iterator(_Elems, 0);
    }

    _NODISCARD _CONSTEXPR17 const_iterator begin() const noexcept {
        return const_iterator(_Elems, 0);
    }

    _NODISCARD _CONSTEXPR17 iterator end() noexcept {
        return iterator(_Elems, _Size);
    }

    _NODISCARD _CONSTEXPR17 const_iterator end() const noexcept {
        return const_iterator(_Elems, _Size);
    }

    _NODISCARD _CONSTEXPR17 reverse_iterator rbegin() noexcept {
        return reverse_iterator(end());
    }

    _NODISCARD _CONSTEXPR17 const_reverse_iterator rbegin() const noexcept {
        return const_reverse_iterator(end());
    }

    _NODISCARD _CONSTEXPR17 reverse_iterator rend() noexcept {
        return reverse_iterator(begin());
    }

    _NODISCARD _CONSTEXPR17 const_reverse_iterator rend() const noexcept {
        return const_reverse_iterator(begin());
    }

    _NODISCARD _CONSTEXPR17 const_iterator cbegin() const noexcept {
        return begin();
    }

    _NODISCARD _CONSTEXPR17 const_iterator cend() const noexcept {
        return end();
    }

    _NODISCARD _CONSTEXPR17 const_reverse_iterator crbegin() const noexcept {
        return rbegin();
    }

    _NODISCARD _CONSTEXPR17 const_reverse_iterator crend() const noexcept {
        return rend();
    }

    _CONSTEXPR17 _Ty* _Unchecked_begin() noexcept {
        return _Elems;
    }

    _CONSTEXPR17 const _Ty* _Unchecked_begin() const noexcept {
        return _Elems;
    }

    _CONSTEXPR17 _Ty* _Unchecked_end() noexcept {
        return _Elems + _Size;
    }

    _CONSTEXPR17 const _Ty* _Unchecked_end() const noexcept {
        return _Elems + _Size;
    }

    _NODISCARD constexpr size_type size() const noexcept {
        return _Size;
    }

    _NODISCARD constexpr size_type max_size() const noexcept {
        return _Size;
    }

    _NODISCARD constexpr bool empty() const noexcept {
        return false;
    }

    _NODISCARD _CONSTEXPR17 reference at(size_type _Pos) {
        if (_Size <= _Pos) {
            _Xran();
        }

        return _Elems[_Pos];
    }

    _NODISCARD constexpr const_reference at(size_type _Pos) const {
        if (_Size <= _Pos) {
            _Xran();
        }

        return _Elems[_Pos];
    }

    _NODISCARD _CONSTEXPR17 reference operator[](_In_range_(0, _Size - 1) size_type _Pos) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
        _STL_VERIFY(_Pos < _Size, "array subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0

        return _Elems[_Pos];
    }

    _NODISCARD constexpr const_reference operator[](_In_range_(0, _Size - 1) size_type _Pos) const noexcept
    /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
        _STL_VERIFY(_Pos < _Size, "array subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0

        return _Elems[_Pos];
    }

    _NODISCARD _CONSTEXPR17 reference front() noexcept /* strengthened */ {
        return _Elems[0];
    }

    _NODISCARD constexpr const_reference front() const noexcept /* strengthened */ {
        return _Elems[0];
    }

    _NODISCARD _CONSTEXPR17 reference back() noexcept /* strengthened */ {
        return _Elems[_Size - 1];
    }

    _NODISCARD constexpr const_reference back() const noexcept /* strengthened */ {
        return _Elems[_Size - 1];
    }

    _NODISCARD _CONSTEXPR17 _Ty* data() noexcept {
        return _Elems;
    }

    _NODISCARD _CONSTEXPR17 const _Ty* data() const noexcept {
        return _Elems;
    }

    [[noreturn]] void _Xran() const {
        _Xout_of_range("invalid array<T, N> subscript");
    }

    _Ty _Elems[_Size];
};

#if _HAS_CXX17
template <class _First, class... _Rest>
struct _Enforce_same {
    static_assert(conjunction_v<is_same<_First, _Rest>...>,
        "N4687 26.3.7.2 [array.cons]/2: "
        "Requires: (is_same_v<T, U> && ...) is true. Otherwise the program is ill-formed.");
    using type = _First;
};

/// 检查数组中元素类型与第一个要严格一致
template <class _First, class... _Rest>
array(_First, _Rest...) -> array<typename _Enforce_same<_First, _Rest...>::type, 1 + sizeof...(_Rest)>;
#endif // _HAS_CXX17


/// 数组模板偏特化
template <class _Ty>
class array<_Ty, 0> {
public:
    using value_type      = _Ty;
    using size_type       = size_t;
    using difference_type = ptrdiff_t;
    using pointer         = _Ty*;
    using const_pointer   = const _Ty*;
    using reference       = _Ty&;
    using const_reference = const _Ty&;

    using iterator               = _Array_iterator<_Ty, 0>;
    using const_iterator         = _Array_const_iterator<_Ty, 0>;
    using reverse_iterator       = _STD reverse_iterator<iterator>;
    using const_reverse_iterator = _STD reverse_iterator<const_iterator>;

#if _HAS_TR1_NAMESPACE
    _DEPRECATE_TR1_NAMESPACE void assign(const _Ty&) {}
#endif // _HAS_TR1_NAMESPACE

    _CONSTEXPR20 void fill(const _Ty&) {}

    _CONSTEXPR20 void swap(array&) noexcept {}

    _NODISCARD _CONSTEXPR17 iterator begin() noexcept {
        return iterator{};
    }

    _NODISCARD _CONSTEXPR17 const_iterator begin() const noexcept {
        return const_iterator{};
    }

    _NODISCARD _CONSTEXPR17 iterator end() noexcept {
        return iterator{};
    }

    _NODISCARD _CONSTEXPR17 const_iterator end() const noexcept {
        return const_iterator{};
    }

    _NODISCARD _CONSTEXPR17 reverse_iterator rbegin() noexcept {
        return reverse_iterator(end());
    }

    _NODISCARD _CONSTEXPR17 const_reverse_iterator rbegin() const noexcept {
        return const_reverse_iterator(end());
    }

    _NODISCARD _CONSTEXPR17 reverse_iterator rend() noexcept {
        return reverse_iterator(begin());
    }

    _NODISCARD _CONSTEXPR17 const_reverse_iterator rend() const noexcept {
        return const_reverse_iterator(begin());
    }

    _NODISCARD _CONSTEXPR17 const_iterator cbegin() const noexcept {
        return begin();
    }

    _NODISCARD _CONSTEXPR17 const_iterator cend() const noexcept {
        return end();
    }

    _NODISCARD _CONSTEXPR17 const_reverse_iterator crbegin() const noexcept {
        return rbegin();
    }

    _NODISCARD _CONSTEXPR17 const_reverse_iterator crend() const noexcept {
        return rend();
    }

    _CONSTEXPR17 _Ty* _Unchecked_begin() noexcept {
        return nullptr;
    }

    _CONSTEXPR17 const _Ty* _Unchecked_begin() const noexcept {
        return nullptr;
    }

    _CONSTEXPR17 _Ty* _Unchecked_end() noexcept {
        return nullptr;
    }

    _CONSTEXPR17 const _Ty* _Unchecked_end() const noexcept {
        return nullptr;
    }

    _NODISCARD constexpr size_type size() const noexcept {
        return 0;
    }

    _NODISCARD constexpr size_type max_size() const noexcept {
        return 0;
    }

    _NODISCARD constexpr bool empty() const noexcept {
        return true;
    }

    [[noreturn]] reference at(size_type) {
        _Xran();
    }

    [[noreturn]] const_reference at(size_type) const {
        _Xran();
    }

    _NODISCARD reference operator[](size_type) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
        _STL_REPORT_ERROR("array subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0

        return _Elems[0];
    }

    _NODISCARD const_reference operator[](size_type) const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
        _STL_REPORT_ERROR("array subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0

        return _Elems[0];
    }

    _NODISCARD reference front() noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
        _STL_REPORT_ERROR("array<T, 0>::front() invalid");
#endif // _CONTAINER_DEBUG_LEVEL > 0

        return _Elems[0];
    }

    _NODISCARD const_reference front() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
        _STL_REPORT_ERROR("array<T, 0>::front() invalid");
#endif // _CONTAINER_DEBUG_LEVEL > 0

        return _Elems[0];
    }

    _NODISCARD reference back() noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
        _STL_REPORT_ERROR("array<T, 0>::back() invalid");
#endif // _CONTAINER_DEBUG_LEVEL > 0

        return _Elems[0];
    }

    _NODISCARD const_reference back() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
        _STL_REPORT_ERROR("array<T, 0>::back() invalid");
#endif // _CONTAINER_DEBUG_LEVEL > 0

        return _Elems[0];
    }

    _NODISCARD _CONSTEXPR17 _Ty* data() noexcept {
        return nullptr;
    }

    _NODISCARD _CONSTEXPR17 const _Ty* data() const noexcept {
        return nullptr;
    }

    [[noreturn]] void _Xran() const {
        _Xout_of_range("invalid array<T, 0> subscript");
    }

    _Ty _Elems[1];
};

template <class _Ty, size_t _Size, enable_if_t<_Size == 0 || _Is_swappable<_Ty>::value, int> = 0>
_CONSTEXPR20 void swap(array<_Ty, _Size>& _Left, array<_Ty, _Size>& _Right) noexcept(noexcept(_Left.swap(_Right))) {
    return _Left.swap(_Right);
}

template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR20 bool operator==(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
#ifdef __EDG__ // TRANSITION, VSO-1161663
    return _STD equal(_Left.begin(), _Left.end(), _Right.begin());
#else // ^^^ workaround / no workaround vvv
    return _STD equal(_Left._Unchecked_begin(), _Left._Unchecked_end(), _Right._Unchecked_begin());
#endif // ^^^ no workaround ^^^
}

#if !_HAS_CXX20
template <class _Ty, size_t _Size>
_NODISCARD bool operator!=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
    return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Ty, size_t _Size>
_NODISCARD constexpr _Synth_three_way_result<_Ty> operator<=>(
    const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
#ifdef __EDG__ // TRANSITION, VSO-1161663
    return _STD lexicographical_compare_three_way(
        _Left.begin(), _Left.end(), _Right.begin(), _Right.end(), _Synth_three_way{});
#else // ^^^ workaround / no workaround vvv
    return _STD lexicographical_compare_three_way(_Left._Unchecked_begin(), _Left._Unchecked_end(),
        _Right._Unchecked_begin(), _Right._Unchecked_end(), _Synth_three_way{});
#endif // ^^^ no workaround ^^^
}
#else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv
template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR20 bool operator<(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
#ifdef __EDG__ // TRANSITION, VSO-1161663
    return _STD lexicographical_compare(_Left.begin(), _Left.end(), _Right.begin(), _Right.end());
#else // ^^^ workaround / no workaround vvv
    return _STD lexicographical_compare(
        _Left._Unchecked_begin(), _Left._Unchecked_end(), _Right._Unchecked_begin(), _Right._Unchecked_end());
#endif // ^^^ no workaround ^^^
}

template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR20 bool operator>(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
    return _Right < _Left;
}

template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR20 bool operator<=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
    return !(_Right < _Left);
}

template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR20 bool operator>=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
    return !(_Left < _Right);
}
#endif // ^^^ !defined(__cpp_lib_concepts) ^^^

#if _HAS_CXX20
template <class _Ty, size_t _Size, size_t... _Idx>
_NODISCARD constexpr array<remove_cv_t<_Ty>, _Size> _To_array_lvalue_impl(
    _Ty (&_Array)[_Size], index_sequence<_Idx...>) {
    return {{_Array[_Idx]...}};
}

template <class _Ty, size_t _Size, size_t... _Idx>
_NODISCARD constexpr array<remove_cv_t<_Ty>, _Size> _To_array_rvalue_impl(
    _Ty(&&_Array)[_Size], index_sequence<_Idx...>) {
    return {{_STD move(_Array[_Idx])...}};
}

template <class _Ty, size_t _Size>
_NODISCARD constexpr array<remove_cv_t<_Ty>, _Size> to_array(_Ty (&_Array)[_Size]) {
    static_assert(!is_array_v<_Ty>, "N4830 [array.creation]/1: "
                                    "to_array does not accept multidimensional arrays.");
    static_assert(is_constructible_v<_Ty, _Ty&>, "N4830 [array.creation]/1: "
                                                 "to_array requires copy constructible elements.");
    return _To_array_lvalue_impl(_Array, make_index_sequence<_Size>{});
}

template <class _Ty, size_t _Size>
_NODISCARD constexpr array<remove_cv_t<_Ty>, _Size> to_array(_Ty(&&_Array)[_Size]) {
    static_assert(!is_array_v<_Ty>, "N4830 [array.creation]/4: "
                                    "to_array does not accept multidimensional arrays.");
    static_assert(is_move_constructible_v<_Ty>, "N4830 [array.creation]/4: "
                                                "to_array requires move constructible elements.");
    return _To_array_rvalue_impl(_STD move(_Array), make_index_sequence<_Size>{});
}
#endif // _HAS_CXX20

template <size_t _Idx, class _Ty, size_t _Size>
_NODISCARD constexpr _Ty& get(array<_Ty, _Size>& _Arr) noexcept {
    static_assert(_Idx < _Size, "array index out of bounds");
    return _Arr._Elems[_Idx];
}

template <size_t _Idx, class _Ty, size_t _Size>
_NODISCARD constexpr const _Ty& get(const array<_Ty, _Size>& _Arr) noexcept {
    static_assert(_Idx < _Size, "array index out of bounds");
    return _Arr._Elems[_Idx];
}

template <size_t _Idx, class _Ty, size_t _Size>
_NODISCARD constexpr _Ty&& get(array<_Ty, _Size>&& _Arr) noexcept {
    static_assert(_Idx < _Size, "array index out of bounds");
    return _STD move(_Arr._Elems[_Idx]);
}

template <size_t _Idx, class _Ty, size_t _Size>
_NODISCARD constexpr const _Ty&& get(const array<_Ty, _Size>&& _Arr) noexcept {
    static_assert(_Idx < _Size, "array index out of bounds");
    return _STD move(_Arr._Elems[_Idx]);
}

#if _HAS_TR1_NAMESPACE
namespace _DEPRECATE_TR1_NAMESPACE tr1 {
    using _STD array;
    using _STD get;
} // namespace tr1
#endif // _HAS_TR1_NAMESPACE
_STD_END

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // _STL_COMPILER_PREPROCESSOR
#endif // _ARRAY_

从源码来看,非常经典而简洁,在我们平时自己使用元编程技巧时,有不错的借鉴意义。而且这一段难度比较低,基本上大家应该都能看得懂。
std::array 在底层实现上,还是依赖于 基础数组 这一数据类型,以下源码可以佐证。

template <class _Ty, size_t _Size>
class array { // fixed size array of values
    _Ty _Elems[_Size];  // 数组
};

个人喜欢std::arrayOOP ,不过std::array 也有觉得可以优化的地方,譬如不支持弹性数组的特性,不支持扩容,不支持参数化列表初始化等,不过,这也许正是设计者设计std::array如此简洁优雅之意图。
编程,不只是技术,深入去思考,会觉得简直就是艺术~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1336401.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在Centos7中利用Shell脚本:实现MySQL的数据备份

目录 自动化备份MySQL 一.备份数据库脚本 1.创建备份目录 2.创建脚本文件 3.新建配置文件&#xff08;连接数据库的配置文件&#xff09; 4.给文件权限(mysql_backup.sh) ​编辑 5.执行命令 (mysql_backup.sh) ​编辑 二.数据库通过备份恢复 1.创建脚…

jsonhandle 插件下载

网盘地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1hj4GKuGNyDNP2JzsJTLFtg 提取码&#xff1a;87rw 1.打开谷歌浏览器&#xff0c;选择扩展程序&#xff0c;记得选择为开发者模式&#xff0c;然后把下载好的CRX文件拖进去就行了

TCP通信流程

// TCP 和 UDP -> 传输层的协议 UDP : 用户数据报协议&#xff0c;面向无连接&#xff0c;可以单播&#xff0c;多播&#xff0c;广播&#xff0c; 面向数据报&#xff0c;不可靠&#xff08;接受方不会存储数据&#xff0c;也没有拥塞控制&#xff09;。效率高&#xff…

二维码智慧门牌管理系统升级:高效授权精准控制

文章目录 前言一、精确权限控制二、角色权限受限与透明操作三、提升工作效率与安全性 前言 二维码智慧门牌管理系统在企业管理中扮演着愈发重要的角色。通过系统升级&#xff0c;管理员可以配置权限角色&#xff0c;为单个或多个用户赋权&#xff0c;实现精准控制&#xff0c;…

如何进行镜像管理

目录 镜像管理 创建自定义镜像 自定义镜像管理 自定义镜像管理方法 对于传统的物理服务器&#xff0c;就要基于现有服务器磁盘制作操作系统镜像&#xff0c;系统镜像可以简单理解成把操作系统中包含的一系列文件通过镜子映射出一模一样的文件并进行打包压缩&#xff0c;就变…

Flowable-升级为7.0.0.M2-第二节

目录 替换变化的类和配置把javax.servlet 替换为 jakarta.servlet修改redis的配置配置logging.level.org.springframework.boot.autoconfigureerror避免影响视听 替换变化的类和配置 把javax.servlet 替换为 jakarta.servlet import javax.servlet.ServletContext; import ja…

AI赋能金融创新:ChatGPT引领量化交易新时代

文章目录 一、引言二、ChatGPT与量化交易的融合三、实践应用&#xff1a;ChatGPT在量化交易中的成功案例四、挑战与前景五、结论《AI时代Python量化交易实战&#xff1a;ChatGPT让量化交易插上翅膀》&#x1f4da;→ [当当](http://product.dangdang.com/29658180.html) | [京东…

【JavaScript】原型对象 => 原型链的深入浅出解读

文章目录 先知概念&#xff1a;原型 prototype隐式原型 __ proto __原型链 先知概念&#xff1a; 在了解原型与原型链之前&#xff0c;我们应该要先明确以下几个概念&#xff1a; 1. 在 JS中 所有的普通对象 都是 通过 new 一个函数来创建的。 2. 在 JS中 所有的函数 本质上也是…

开源问答类知识网站源码系统 附带完整的搭建教程

人们对知识的需求和获取方式也在发生改变。问答类知识网站成为了人们获取答案、解决问题的重要途径之一。然而&#xff0c;由于问答类知识网站需要处理大量的用户提问和回答&#xff0c;因此对于技术的要求也相对较高。小编给大家分享一款开源问答类知识网站源码系统&#xff0…

【Git版本控制】

Day10_Git版本控制 知识点01&#xff1a;课程内容大纲与学习目标 #课程内容大纲版本控制工具Git ​ #学习目标了解下git的背景以及作用了解下git基本使用 知识点02&#xff1a;项目开发中的版本问题 目标&#xff1a;了解项目开发中遇到的开发版本问题 举例&#xff1a;你在大…

广播测试信令记录一文全解

语音广播基本要求 语音广播功能实现用户通过语音输入设备向前端语音输出设备的语音广播。语音流发送者向语音流接收者发送通知消息&#xff0c;语音流接受者在收到通知消息后&#xff0c;进行判断处理。若能够接收广播&#xff0c;则向语音流发送者发起呼叫请求&#xff0c;获…

408数据结构错题知识点拾遗

408相关&#xff1a; 408数据结构错题知识点拾遗 408计算机网络错题知识点拾遗 对于数据结构的学习&#xff0c;个人认为要对概念性的东西进行理解&#xff0c;特别是树的性质、图的相关性质和考察的相应算法。应用题强化的话&#xff0c;对于每一章节尾的应用小节&#xff0c…

【开源】基于JAVA的学校热点新闻推送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 新闻类型模块2.2 新闻档案模块2.3 新闻留言模块2.4 新闻评论模块2.5 新闻收藏模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 新闻类型表3.2.2 新闻表3.2.3 新闻留言表3.2.4 新闻评论表3.2.5 新闻收藏表 四、系统展…

Unity网格篇Mesh(一)

Unity网格篇Mesh&#xff08;一&#xff09; 本文的目标1.渲染仔细看下面的图你会发现&#xff0c;锯齿状 2.创建网格顶点4 x 2网格网格的顶点 3.创建网格网格只在Play模式下显示逆时针和顺时针三角形第一个三角面一个四边形由两个三角面组成第一个四边形填充剩余网格 接下一篇…

Vue使用Element表格Table设置所有单元格内容居中对齐

为单个列的单元格设置居中对齐代码如下&#xff1a; <el-table-columnprop"productInfo.productName"label"中文名"width"100"align"center"></el-table-column>需要设置el-table-column标签里面的属性设置为align"c…

Jenkins Tutorial

什么是Jenkins Jenkins是一个自动化平台&#xff0c;它允许你使用pipelines去部署应用。它也可以自动化其他任务。 BUILDTESTDEPLOYMENT Jenkins 架构 首先&#xff0c;你拥有一个Master Server&#xff0c;它控制pipelines和安排Build到你的Agent上&#xff1b; 其次&…

除法计算器 C语言xdoj48

问题描述 小明的弟弟刚开始学习除法&#xff0c;为了检查弟弟的计算结果是否正确&#xff0c;小明决定设计一个简单计算器程序来验算。 输入说明 输入数据由四个整数m&#xff0c;n&#xff0c;q&#xff0c;r构成&#xff0c;m为被除数&#xff0c;n为除数&#xff0c…

JVM GC 算法原理概述

对于JVM的垃圾收集&#xff08;GC&#xff09;&#xff0c;这是一个作为Java开发者必须了解的内容&#xff0c;那么&#xff0c;我们需要去了解哪些内容呢&#xff0c;其实&#xff0c;GC主要是解决下面的三个问题&#xff1a; 哪些内存需要回收&#xff1f; 什么时候回收&…

Explain分析——索引优化实践

欢迎大家关注我的微信公众号&#xff1a; 本文通过Explain分析进行索引优化&#xff0c;需要对Explain工具有一定的了解。可以先学习Explain详解之后再进行本文的学习。 传送门&#xff1a;Explain详解 示例表&#xff1a; CREATE TABLE employees (id int(11) NOT NULL AUT…

[RL1]深度强化学习基础

一、强化学习 强化学习(reinforce learning, RL)的本质是互动学习&#xff0c;即让智能体与其外界环境进行交互。智能体根据自己每次感知到的外界环境状态来选择相应的动作&#xff0c;以对环境进行响应&#xff0c;然后观测该动作所造成的结果&#xff0c;并根据结果来调整自身…