`std :: array <T,0>`默认是可构造的,其中`T`不是默认可构造的?

Jam*_*ree 15 c++ arrays language-lawyer c++11

请考虑以下代码:

#include <array>

struct T
{
    T() = delete;
};

int main()
{
    std::array<T, 0> a;
    a.size();
}
Run Code Online (Sandbox Code Playgroud)

我们默认初始化一个0大小的数组.由于没有元素,因此不T应该调用构造函数.

但是,Clang仍然需要T默认构造,而GCC接受上面的代码.

请注意,如果我们将数组初始化更改为:

std::array<T, 0> a{};
Run Code Online (Sandbox Code Playgroud)

Clang这次接受了.

非默认构造是否可以T防止std::array<T, 0>默认构造?

Sto*_*ica 5

由于没有元素,因此不应该调用T的构造函数.
非默认构造的T是否可以防止std::array<T, 0>默认构造?

该标准没有规定我们std::array<T, 0>应该采用什么布局来回答这个问题.零大小的数组专门化只表现如下:

[array.zero]

1个数组应该为特殊情况N == 0提供支持
.2在N == 0 的情况下,begin()== end()==唯一值.data()的返回值未指定.
3未定义调用front()或back()对零大小数组的影响.
4成员函数swap()应具有非抛出异常规范.

您注意到的行为很可能是由于实施方面的差异.


Jam*_*ree 5

感谢@TC,正如他在评论中指出的那样,它在LWG 2157中得到了解决,在撰写本文时仍然是一个未解决的问题.

拟议的决议增加了这一要点(强调我的):

这种情况下未指定的数组内部结构应允许初始化,如:

array<T, 0> a = { };
Run Code Online (Sandbox Code Playgroud)

并且即使T不是默认可构造的,所述初始化也必须有效.

所以很明显,std::array<T, 0>即使T不是,预期的行为也是默认的可构造性.