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