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)...)