您现在的位置是:首页 >技术杂谈 >c++标准模板(STL)(std::array)(五)网站首页技术杂谈
c++标准模板(STL)(std::array)(五)
定义于头文件 <array>
template< class T, | (C++11 起) |
std::array
是封装固定大小数组的容器。
此容器是一个聚合类型,其语义等同于保有一个 C 风格数组 T[N] 作为其唯一非静态数据成员的结构体。不同于 C 风格数组,它不会自动退化成 T* 。它能作为聚合类型聚合初始化,只要有至多 N
个能转换成 T
的初始化器: std::array<int, 3> a = {1,2,3}; 。
该结构体结合了 C 风格数组的性能、可访问性与容器的优点,比如可获取大小、支持赋值、随机访问迭代器等。
std::array
满足容器 (Container) 和可逆容器 (ReversibleContainer) 的要求,除了默认构造的 array 是非空的,以及进行交换的复杂度是线性,它满足连续容器 (ContiguousContainer) (C++17 起)的要求并部分满足序列容器 (SequenceContainer) 的要求。
当其长度为零时 array
( N == 0
)有特殊情况。此时, array.begin() == array.end() ,并拥有某个唯一值。在零长 array
上调用 front() 或 back() 是未定义的。
亦可将 array
当做拥有 N
个同类型元素的元组。
迭代器非法化
按照规则,指向 array
的迭代器在 array
的生存期间决不非法化。然而要注意,在 swap 时,迭代器将继续指向同一 array
的元素,并将改变元素的值。
非成员函数
按照字典顺序比较 array 中的值
operator==,!=,<,<=,>,>=(std::array)
template< class T, std::size_t N > bool operator==( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (1) | (C++20 前) |
template< class T, std::size_t N > constexpr bool operator==( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (C++20 起) | |
template< class T, std::size_t N > bool operator!=( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (2) | (C++20 前) |
template< class T, std::size_t N > constexpr bool operator!=( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (C++20 起) | |
template< class T, std::size_t N > bool operator<( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (3) | (C++20 前) |
template< class T, std::size_t N > constexpr bool operator<( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (C++20 起) | |
template< class T, std::size_t N > bool operator<=( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (4) | (C++20 前) |
template< class T, std::size_t N > constexpr bool operator<=( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (C++20 起) | |
template< class T, std::size_t N > bool operator>( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (5) | (C++20 前) |
template< class T, std::size_t N > constexpr bool operator>( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (C++20 起) | |
template< class T, std::size_t N > bool operator>=( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (6) | (C++20 前) |
template< class T, std::size_t N > constexpr bool operator>=( const std::array<T, N>& lhs, const std::array<T, N>& rhs ); | (C++20 起) |
比较二个 array
的内容。
1-2) 检查 lhs
与 rhs
的内容是否相等,即 lhs
中的每个元素是否与 rhs
中同一位置的元素比较相等。
3-6) 按字典序比较 lhs
与 rhs
的内容。由等价于 std::lexicographical_compare 的函数进行比较。
参数
lhs, rhs | - | 要比较内容的容器 |
- 为使用重载 (1-2) , T 必须满足可相等比较 (EqualityComparable) 的要求。 | ||
- 为使用重载 (3-6) , T 必须满足可小于比较 (LessThanComparable) 的要求。顺序关系必须建立全序。 |
返回值
1) 若容器内容相等则为 true ,否则为 false 。
2) 若容器的内容不相等则为 true ,否则为 false 。
3) 若 lhs
的内容按字典序小于 rhs
的内容则为 true ,否则为 false 。
4) 若 lhs
的内容按字典序小于或等于 rhs
的内容则为 true ,否则为 false 。
5) 若 lhs
的内容按字典序大于 rhs
的内容则为 true ,否则为 false 。
6) 若 lhs
的内容按字典序大于或等于 rhs
的内容则为 true ,否则为 false 。
复杂度
与容器大小成线性。
访问 array 的一个元素
std::get(std::array)
template< size_t I, class T, size_t N > | (1) | (C++11 起) |
template< size_t I, class T, size_t N > | (2) | (C++11 起) |
template< size_t I, class T, size_t N > | (3) | (C++11 起) |
template< size_t I, class T, size_t N > | (4) | (C++17 起) |
从 array 提取第 Ith
个元素。
I
必须是范围 [0, N)
中的整数值。与 at() 或 operator[] 相反,这在编译时强制。
参数
a | - | 要提取其内容的数组 |
返回值
到 a
的 Ith
元素的引用。
时间复杂度
常数。
特化 std::swap 算法
std::swap(std::array)
template< class T, std::size_t N > void swap( array<T,N>& lhs, array<T,N>& rhs ); | (C++11 起) (C++17 前) | |
template< class T, std::size_t N > void swap( array<T,N>& lhs, array<T,N>& rhs ) noexcept(/* see below */); | (C++17 起) (C++20 前) | |
template< class T, std::size_t N > constexpr void swap( array<T,N>& lhs, array<T,N>& rhs ) noexcept(/* see below */); | (C++20 起) |
为 std::array 特化 std::swap 算法。交换 lhs
与 rhs
的内容。调用 lhs.swap(rhs) 。
此重载仅若 | (C++17 起) |
参数
lhs, rhs | - | 要交换内容的容器 |
返回值
(无)
复杂度
与容器大小成线性。
异常
noexcept 规定: noexcept(noexcept(lhs.swap(rhs))) | (C++17 起) |
从内建数组创建 std::array 对象
std::to_array
template<class T, std::size_t N> | (1) | (C++20 起) |
template<class T, std::size_t N> | (2) | (C++20 起) |
从一维内建数组 a
创建 std::array 。从 a
的对应元素复制初始化 std::array
的元素。不支持复制或移动多维内建数组。
1) 对 0, ..., N - 1
中的每个 i
,以 a[i] 复制初始化结果的对应元素。若 std::is_constructible_v<T, T&> 为 false 则此重载为病式。
2) 对 0, ..., N - 1
中的每个 i
,以 std::move(a[i]) 复制初始化结果的对应元素。若 std::is_move_constructible_v<T> 为 false 则此重载为病式。
std::is_array_v<T> 为 true 时两个重载均为病式。
参数
a | - | 要转换成 std::array 的内建数组 |
类型要求 | ||
- 为使用重载 (1) , T 必须满足可复制构造 (CopyConstructible) 的要求。 | ||
- 为使用重载 (2) , T 必须满足可移动构造 (MoveConstructible) 的要求。 |
返回值
1) std::array<std::remove_cv_t<T>, N>{ a[0], ..., a[N - 1] }
2) std::array<std::remove_cv_t<T>, N>{ std::move(a[0]), ..., std::move(a[N - 1]) }
注解
有一些不能使用 std::array 的类模板实参推导而 to_array
可用的情况:
to_array
能在手工指定std::array
的元素类型并推导长度时指定,这在想要隐式转换时会更好。to_array
能赋值字符串字面量,而类模板实参推导创建有一个指向其首字符的std::array
。
std::to_array<long>({3, 4}); // OK :隐式转换
// std::array<long>{3, 4}; // 错误:模板参数太少
std::to_array("foo"); // 创建 std::array<char, 4>{ 'f', 'o', 'o', '