1

There are many questions and answers about initializing an std::array data member with a std::initializer_list and how it's not possible because there is no constructor for the std::array available that takes . I would like to know how does the initialization of the std::array then work?

What happens under the hood when a call like this is made:

std::array<int, 4> a = {1,2,3,4};  // (1)

How is the argument then interpreted, if it is not an std::initializer_list<int>?

I have tried to figure how the initialization works by looking at the libstdc++ source code, and figuring out what is done with the _M_elems (__array_traits::_Tp), but I can't seem find either the actual allocation of an array that stores the data. I see it being used all over the place however:

       // Element access.
       _GLIBCXX17_CONSTEXPR reference
       operator[](size_type __n) noexcept
  { return _AT_Type::_S_ref(_M_elems, __n); }

And _S_ref is a constexpr function that seems to return a nullptr?

Where is the actual array data declared? I could understand if the compiler does something behind the scenes, as all the constructors are generated automatically, but I would like to know what happens and how is the initialization call (1) possible.

Also, if I use an std::array as a data member for an N-dimensional Point, I have found an answer that proposes something like this:

template<std::size_t N, typename BT=double>
class Point 
{
    public: 

        Point() = default;

        template<typename ... Args>
        Point(Args&& ... args)
        :
            values_{std::forward<Args>(args)...} 
        {}

    private:

        std::array<BT, N>  values_; 
};

Which makes it possible to do

Point<1> P1 {1.};   // (2)
Point<3> P3 {1.,2.,3.}; // (3)

I understand that the forward is required because (what I understand as) initializer lists used in (2,3) are lvalues. However, why is the curly bracket necessary? If I use a round bracket to initialize values_

            values_(std::forward<Args>(args)...)    

I get

main.cpp: In instantiation of ‘Point<N, BT>::Point(Args&& ...) [with Args = {double}; long unsigned int N = 1; BT = double]’:
main.cpp:37:20:   required from here
main.cpp:14:48: error: no matching function for call to ‘std::array<double, 1>::array(double)’
             values_(std::forward<Args>(args)...)
tmaric
  • 5,347
  • 4
  • 42
  • 75
  • 4
    [`std::array`](https://en.cppreference.com/w/cpp/container/array) is an *aggregate* and initialization works because of [aggregate initialization](https://en.cppreference.com/w/cpp/language/aggregate_initialization). – Some programmer dude Jan 09 '19 at 11:50

0 Answers0