Is `std::array` default constructible where `T` is not default constructible?

后端 未结 3 1897
谎友^
谎友^ 2021-01-08 00:18

Consider the code below:

#include 

struct T
{
    T() = delete;
};

int main()
{
    std::array a;
    a.size();
}
<
3条回答
  •  -上瘾入骨i
    2021-01-08 00:43

    This question explains what happens with clang and std::array Deleted default constructor. Objects can still be created... sometimes

    But with gcc the difference comes from the library code. There is indeed a specific implementation detail in the gcc codebase that is relevant to this question as @StoryTeller mentioned

    gcc has a special case for std::array with a size of 0, see the following code from their header (from gcc 5.4.0)

    template
    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
    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; }
    };
    

    as you can see, there is a specialization of __array_traits (which is used in std::array for the underlying array) when the array size is 0, that doesn't even have an array of the type it's templated on. The type _Type is not an array, but an empty struct!

    That is why there are no constructors invoked.

提交回复
热议问题