Given any std::array< T, 0 >
, why is it not empty? I mean "empty" as in:
std::is_empty< std::array< int, 0 > >::value
... returning false
, and
#include <iostream>
#include <tuple>
#include <array>
struct Empty {};
int main()
{
std::cout << sizeof(std::tuple<int>) << std::endl;
std::cout << sizeof(std::tuple<int,Empty>) << std::endl;
std::cout << sizeof(std::tuple<int,std::array<int,0>>) << std::endl;
}
yields
4
4
8
This means that for std::array<int,0>
, the empty base optimization (EBO) is not applied.
This seem especially strange to me given that std::tuple<>
(note: no template parameters) is empty, i.e., std::is_empty<std::tuple<>>::value
does yield true
.
Question: Why is that, given that size 0
is already a special case for std::array
? Is it intentional or an oversight in the standard?
The standard doesn't say anything about whether tuple
or array
should be empty, what you're seeing are implementation details, but there's no reason to make tuple<>
non-empty, whereas there is a good reason for array<T, 0>
being non-empty, consider:
std::array<int, sizeof...(values)> = { { values... } };
When the parameter pack is empty you'd get:
std::array<int, 0> = { { } };
For the initializer to be valid the object needs a member, which cannot be int[0]
because you can't have zero-sized arrays as members, so a possible implementation is int[1]
An implementation doesn't have to special case the whole array, it can just do:
T m_data[N == 0 ? 1 : N];
and all other members work exactly the same way (assuming end()
is defined as begin()+N
)