在C ++ 11中是否有一个零大小的std :: array的原因?

考虑下面的一段代码,C ++ 11编译器完全可以接受这段代码:

#include <array> #include <iostream> auto main() -> int { std::array<double, 0> A; for(auto i : A) std::cout << i << std::endl; return 0; } 

根据标准§23.3.2.8[ 零尺寸arrays ]:

1arrays应提供对特殊情况N == 0

2N == 0的情况下, begin() == end() ==唯一值。 返回值
data()是未指定的。

3调用front()back()调用一个零大小的数组是没有定义的。

4成员函数swap()应该有一个noexcept-speci fi cation,相当于noexcept(true)

如上所示,在C ++ 11中,零大小的std::array是完全允许的,与零大小的数组(例如, int A[0]; )相比,它们被明确禁止,但它们被一些编译器例如GCC)以未定义的行为为代价。

考虑到这个“矛盾”,我有以下几个问题:

  • 为什么C ++委员会决定允许零大小的std::array s?

  • 有什么有价值的用途吗?

如果你有一个generics函数,如果这个函数随机破解了特殊的参数,这是不好的。 例如,假设你可以有一个模板函数,它使N随机元素构成一个向量:

 template<typename T, size_t N> std::array<T, N> choose(const std::vector<T> &v) { ... } 

如果由于某种原因导致N为零,则会导致未定义的行为或编译器错误。

对于原始数组而言,限制背后的原因是您不希望sizeof T == 0types,这会导致与指针算术结合的奇怪效果。 如果不为其添加任何特殊规则,那么包含零元素的数组的大小为零。

但是std::array<>是一个类,类总是大于0.所以你不会遇到std::array<> ,并且没有任何限制的参数。

我可以想到的一个用途是零长度数组的返回是可能的,并且具有被特别检查的function。

例如请参阅关于std::array函数empty()的文档。 它有以下返回值:

 true if the array size is 0, false otherwise. 

http://www.cplusplus.com/reference/array/array/empty/

我认为返回和检查长度为0的数组的能力符合其他stltypes实现的标准,例如。 vector和地图,因此是有用的。

与其他容器类一样,能够拥有一个表示一系列事物的对象并使该数组成为空或变为空是有用的。 如果这是不可能的,那么就需要创build另一个对象,或一个pipe理类,以合法的方式来表示这个状态。 拥有所有容器类的能力是非常有帮助的。 在使用它的时候,只需要养成将数组作为一个容器的习惯,这个容器可能是空的,并且在引用它的成员之前检查它的大小或索引,如果它不指向任何东西的话。

实际上有不less情况下,你想能够做到这一点。 它也出现在很多其他语言中。 例如,Java实际上有Collections.emptyList() ,它返回的不仅是大小为零的列表,而且不能被扩展,resize或修改。

例如,如果您有class级代表巴士和该class级的乘客名单。 该列表可能是懒惰初始化,只有当乘客登上时才创build。 如果有人调用getPassengers()那么可以返回一个空列表,而不是每次创build一个新列表来报告空。

返回null也会对类的内部效率起作用,但是如果每次调用getPassengers()时都会使生活变得复杂得多,因为您需要对结果进行空检查。 相反,如果你得到一个空列表,那么只要你的代码没有假设列表不是空的,你不需要任何特殊的代码来处理它为空。