Is it legal to have a std :: array array of a C-style array?

Can I use something like std::array<int[2][2], 2> as a replacement for int[2][2][2] , just like std::array<int, 2> can be used instead of int[2] ?

I really need a possibly multidimensional array of static size that

  • Have the "correct" semantics of values ​​and
  • Stored in memory in memory.

It seems that unlike C-style arrays, std::array of std::array does not guarantee fully compressed memory, since std::array may contain indentation.

What could be the problems that may arise if I use something like std::array<int[2][2], 2> ? Perhaps this is too vague a question, but it is difficult to understand why it is inconvenient and somewhat doubtful for me to use it for my purposes.

+7
c ++ arrays
source share
1 answer

No, this leads to undefined behavior.

value_type container must be erased from the container type , where Erasable is defined in [container.requirements.general] clause 15 :

Given the type of dispenser A and given the type of container X having value_type identical to T and allocator_type identical to allocator_traits<A>​::​rebind_alloc<T> , and given lvalue m type A , a pointer p type T* , an expression of v type (possibly const ) T and rvalue rv type T , the following terms are defined. If X not a distributor, the terms below are defined as if they were a allocator<T> - you do not need to create a distributor object, and user allocator<T> specializations are not created:

  • ...

  • T Erasable from X means that the following expression is well formed: allocator_traits<A>::destroy(m, p)

Since std::array not a means of allocating a distributor, we need to check whether allocator_traits<allocator<int[2][2]>>::destroy(m, p) correctly formed.

Since std::allocator does not have a destroy member function (deprecated in C ++ 17), std::allocator_traits::destroy will directly refer to (pseudo) destrutor int[2][2] . This one is poorly formed because int[2][2] not a scalar type .

+2
source share

All Articles