Why I can't desalinize std::array like this?
#include <array>
struct Point
{
    float x;
    float y;
};
int main()
{
   std::array<Point, 3> m_points { 
      { 1.0f, 1.0f }, 
      { 2.0f, 2.0f }, 
      { 3.0f, 3.0f }
   };
}
Doing this I get error:
error: too many initializers for
std::array<Point, 3ul>
but it works like this:
std::array<Point, 3> m_points { 
   Point{ 1.0f, 1.0f }, 
   Point{ 2.0f, 2.0f }, 
   Point{ 3.0f, 3.0f } 
};
In contrast std::map can be initialized with both ways written below:
   std::map<int, int> m1 {std::pair<int, int>{1,2}, std::pair<int, int>{3,4}}; 
   std::map<int, int> m2 {{1,2}, {3,4}};
                In this declaration and initialization
   std::array<Point, 3> m_points { 
      { 1.0f, 1.0f }, 
      { 2.0f, 2.0f }, 
      { 3.0f, 3.0f }
   };
the compiler considers the first initializer in braces like the initializer of the whole array (of the internal aggregate). std::array is an aggregate that contains another aggregate.
Write instead
   std::array<Point, 3> m_points {
      { 
      { 1.0f, 1.0f }, 
      { 2.0f, 2.0f }, 
      { 3.0f, 3.0f }
      }
   };
In the second case
std::array<Point, 3> m_points { 
   Point{ 1.0f, 1.0f }, 
   Point{ 2.0f, 2.0f }, 
   Point{ 3.0f, 3.0f } 
};
each initializer is considered sequentially as an initializer of a next element of the internal aggregate.
Consider this simple demonstrative program.
#include <iostream>
struct array
{
    int a[10];
};
int main()
{
    array a = { { 0, 0 }, { 1, 1 } };
    return 0;
}
The compiler issues an error like
prog.cpp:14:33: error: too many initializers for 'array'
  array a = { { 0, 0 }, { 1, 1 } };
                                 ^
That is it decided that { 0, 0 } is an initializer of the internal array (internal aggregate). Thus the next initializer in braces does not have a corresponding data member in the outer aggregate (structure).
std::array has no explicitly defined constructors, unlike other standard containers such as std::vector or std::map, but only the automatically provided constructors. With std::vector, the compiler will try to match your expression against each available constructor and for a construct like
std::vecor<Point> m_points { {1.0f,1.0f}, {2.0f,2.0f}, {3.0f,3.0f} };
finds a match with the constructor
std::vector::vector(initializer_list<T>, const Allocator& = Allocator() );
But with std::array, it must use aggregate initialisation of the underlying array (Point[3] in your case) and hence your construction does not match. To get it to work, you must add another pair of braces
std::array<Point, 3> m_points { 
  { { 1.0f, 1.0f },
    { 2.0f, 2.0f }, 
    { 3.0f, 3.0f } }
};
                        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