我有两个问题与std::array
的帮助类std::tuple_size<std::array>
有关。
首先,class std::array
中有一个constexpr成员函数size()
,为什么还需要std::tuple_size<std::array>
?
其次,tuple_size
这个名字是否有误导性?
std::tuple_size
(以及它的朋友 std::tuple_element
和 std::get
)的设计目标不仅是在文字上的 std::tuple
上工作,而且适用于任何类似于元组的东西。类似于元组通常意味着它是一个包含固定数量有序元素的复合类型。
通过查看例如 结构化绑定 的定义,您可以清楚地看到这种抽象的使用:它们允许分解任何具有 std::tuple_size
、std::tuple_element
和 get<I>
的明智实现的东西。
在这种更广泛的“类似于元组”的概念下,std::array
(和 std::pair
)将特殊化这些特性,以处理 N 个相同类型的元组(resp. 大小为 2 的元组)。
这是元组接口的一部分,也是std::array
支持的。元组接口的其他部分是std::tuple_element
和std::get
。
std::array::size
也是多余的,因为大小已作为类型的一部分指定。它作为序列容器接口的一部分存在。
std::tuple_size
和 std::tuple_element
以及名为 get
的函数模板提供了一个通用的接口,用于在模板编程中使用“具有常量计数和类型的对象列表”,而无需指定类型。
#include <utility>
template <class Tuple>
constexpr std::tuple_element_t<Tuple>& get_last(Tuple& t) {
constexpr auto size = std::tuple_size<Tuple>::value;
static_assert(size > 0);
return get<size-1>(t);
}
get_last
函数将适用于std::tuple
,std::pair
,std::array
和任何其他为std::tuple_size
,std::tuple_element
和与类型相关的函数模板get
提供特殊化的用户类型。
此外,语言本身在使用结构化绑定语法时会查找并使用std::tuple_size
,std::tuple_element
和get
。同样,这可以是任何相同的类型,包括实现接口的用户定义类型。
using MyVec = std::array<double, 3>;
void f(const MyVec& v) {
const auto& [x, y, z] = v;
// ...
}