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
which 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?
You can't create an array empty. An array has a fixed size that you can not change. If you want to initialize the array you can put the value as 0 to create an empty array but an array cant have 0 sizes.
Use array::empty() method to check if the array is empty: Instead, it examines if an array is blank or not, that is, if maybe the array's size is zero. If the size of the array becomes zero, this returns 1 which means true. Otherwise, this returns 0 which means false.
std::array does satisfy all the requirements of being a trivial, standard-layout class template. So the answer to your question is yes.
std::array is merely a wrapper around the C-style fixed arrays. to provide type-safety with useful interfaces. Stack-allocation implies that the data for the array is stored in the object itself.
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
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With