C++ - 为什么没有为元组定义 size/ssize(或 tuple_size_v 所在的位置)?

C++ - why isn't size/ssize defined for tuple (or wherever tuple_size_v is)?

我试图想象一个 std::size 不适合 std::tuple 的场景,但我一头雾水。它支持 std::array,但它有自己的 size() 方法,因此无需专门化。但它也支持 T[N],大概是因为它是静态大小的,即使它没有 size() 方法(它甚至没有 std::tuple_size_v。)

那么为什么 std::tuple 没有得到 std::size 支持 size() 方法?我什至认为 std::tuple_size_v 意味着它不需要一个,但 std::array.

也是如此

首先,了解一些背景知识以了解 std::size 甚至是什么目的:

类似于迭代器是指针的概括,标准容器是数组的概括(指针是数组的迭代器)。它们都包含同类类型的元素,即所有元素都具有相同的类型,并且它们可以迭代。

与实际上满足抽象迭代器概念的指针不同,数组没有获得同样的荣誉。这可能是因为 pointer/iterator 的接口可以通过几个简单的操作符来满足,而容器则需要几个函数才能使用。也许委员会更喜欢面向对象的成员函数接口,而不是数组唯一可能的自由函数。

尽管如此,编写通用函数和 类 可以通过同一接口处理数组仍然很有用。尽管在 C++11 (std::array) 中引入了数组包装器模板,它实际上是一个容器(好吧,几乎;它不满足容器需要具有的一些属性),它不能满足所有重构不是一个选项的用例(例如考虑 C 接口)。

C++11 及更高版本还引入了自由函数(模板),它们除了将调用转发给容器的相应成员函数外什么都不做,并使用对数组执行相同操作的模板进行重载。这些重载是可以与模板中的数组和容器一起使用的通用接口。他们是:

std::swap      C++11
std::{c,}begin C++11
std::{c,}end   C++11

std::size      C++17
std::empty     C++17
std::data      C++17

除了通用之外,std::endstd::size 还实现了初学者容易出错的功能。


现在开始提问:

why isn't size/ssize defined for tuple (or wherever tuple_size_v is)?

原提案为n4017。它不包含不支持元组的理由。我不知道委员会是否曾经考虑过它。但如果他们这样做了,因为这样的功能不在标准中,那么他们就会拒绝(至少暂时地)这个想法。

元组不是容器,它没有成员函数size。与数组相比,它离容器的距离要远得多。至关重要的是,元组的元素是异构的;它们由不同类型的对象组成。它们不能像容器一样用迭代器迭代。

然而,元组可以看作是容器的更高泛化。也许在遥远的将来,Boost.Fusion 将被纳入标准,我们将有一个与容器和元组的通用接口。但如果我们在那个时间轴上,那么我们仍然处于相对的过去。它不会发生 until/unless 它已被提议并接受到标准中。


奇怪的是,std::tuple_sizestd::tuplestd::array 之间的通用接口(但不是裸数组)。