这个问题解释铿锵发生了什么和std::array
Deleted default constructor. Objects can still be created... sometimes
但随着gcc
的差异来自于库代码。的确有在GCC代码库的具体实施细节,是有关这个问题的@StoryTeller mentioned
GCC有std::array
大小为0的特殊情况,请参见下面的代码(从GCC 5.4.0
)
他们
<array>
头
template<typename _Tp, std::size_t _Nm>
struct __array_traits
{
typedef _Tp _Type[_Nm];
static constexpr _Tp&
_S_ref(const _Type& __t, std::size_t __n) noexcept
{ return const_cast<_Tp&>(__t[__n]); }
static constexpr _Tp*
_S_ptr(const _Type& __t) noexcept
{ return const_cast<_Tp*>(__t); }
};
template<typename _Tp>
struct __array_traits<_Tp, 0>
{
struct _Type { };
static constexpr _Tp&
_S_ref(const _Type&, std::size_t) noexcept
{ return *static_cast<_Tp*>(nullptr); }
static constexpr _Tp*
_S_ptr(const _Type&) noexcept
{ return nullptr; }
};
你可以看到,有一个__array_traits
特殊化(在std::array
用于底层数组)当阵列大小为0,即甚至没有它的模板上的类型的阵列。类型_Type
不是一个数组,而是一个空的结构!
这就是为什么没有构造函数被调用的原因。
即使有删除的默认构造函数,聚合初始化也是有效的。但是默认初始化(iirc)不是。我认为clangs的行为是合理的。执行或不执行不影响编译时代码是否有效。 –
@ JohannesSchaub-litb你期望一个元素被初始化为一个0大小的数组吗?锵做[that](https://wandbox.org/permlink/LashAGkeVwnfsodC),这看起来很疯狂。如果没有元素,则不应初始化元素。 – Jamboree
参见[LWG 2157](https://timsong-cpp.github.io/lwg-issues/2157)。 –