Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is `std::array<T, 0>` default constructible where `T` is not default constructible?

Consider the code below:

#include <array>

struct T
{
    T() = delete;
};

int main()
{
    std::array<T, 0> a;
    a.size();
}

We default initialize a 0-sized array. Since there's no elements, no constructor of T should be called.

However, Clang still requires T to be default constructible, while GCC accepts the code above.

Note that if we change the array initialization to:

std::array<T, 0> a{};

Clang accepts it this time.

Does non-default-constructible T prevent std::array<T, 0> from being default-constructible?

like image 869
Jamboree Avatar asked Jun 28 '17 10:06

Jamboree


2 Answers

Since there's no elements, no constructor of T should be called.
Does non-default-constructible T prevent std::array<T, 0> from being default-constructible?

The standard doesn't specify what layout std::array<T, 0> should have for us to answer that. The zero sized array specialization is only said to behave as follows:

[array.zero]

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 is undefined.
4 Member function swap() shall have a non-throwing exception specification.

The behavior you note is most probably due to differences in implementation alone.

like image 76
StoryTeller - Unslander Monica Avatar answered Sep 20 '22 16:09

StoryTeller - Unslander Monica


Thanks to @T.C., as pointed out in his comment, it's addressed in LWG 2157, which is still an open issue as of this writing.

The proposed resolution adds this bullet point (emphasis mine):

The unspecified internal structure of array for this case shall allow initializations like:

array<T, 0> a = { };

and said initializations must be valid even when T is not default-constructible.

So it's clear that the intended behavior is to have std::array<T, 0> default constructible even when T is not.

like image 35
Jamboree Avatar answered Sep 20 '22 16:09

Jamboree