yohhoyの日記

技術的メモをしていきたい日記

std::array<T, 0>

C++標準ライブラリの固定長配列型std::array<T, N>では、要素数ゼロN == 0が明示的に許容される。一方で、C++言語組込の配列型においては要素数ゼロが許容されない。*1

C++11 8.3.4/p1, 23.3.2.8より一部引用。

In a declaration T D where D has the form

  D1 [ constant-expressionopt] attribute-specifier-seqopt

and the type of the identifier in the declaration T D1 is "derived-declarator-type-list T", then the type of the identifier of D is an array type; if the type of the identifier of D contains the auto type-specifier, the program is ill-formed. T is called the array element type; this type shall not be a reference type, the (possibly cv-qualified) type void, a function type or an abstract class type. If the constant-expression (5.19) is present, it shall be an integral constant expression and its value shall be greater than zero. The constant expression specifies the bound of (number of elements in) the array. If the value of the constant expression is N, the array has N elements numbered 0 to N-1, and the type of the identifier of D is "derived-declarator-type-list array of N T". (snip)

1 array shall provide support for the special case N == 0.
2 In the case that N == 0, begin() == end() == unique value. The return value of data() is unspecified.
3 The effect of calling front() or back() for a zero-sized array in undefined.
4 Member function swap() shall have a noexcept-specification which is equivalent to noexcept(true).

2003年当時の提案文書N1479 III. Design Decisions より引用(下線部は強調)。

Empty arrays
Consideration should be given to the case where N == 0. For traditional arrays this is an error that should be diagnosed by the compiler. It would be reasonable to retain this behaviour

An alternative offerred by the proposal is to partially specialize the template on the case N == 0, such that it has no internal state, empty() == true, and begin() == end() == 0.

This solution preferred by the proposal removes a potential error from library use. This may be particularly valuable when writing generic code parameterized on N. However, it is a change of behaviour compared to the traditional C array.

関連URL

*1:C言語においても、C言語組込の配列要素数には正数しか許容されない。構造体のフレキシブル配列メンバ(flexible array member)は「要素数ゼロの配列」と似ているが、文法的には配列要素数を指定しない不完全配列型として宣言する必要がある。JPCERT DCL38-C も参照のこと。