Why can't I describe std :: array as follows?

Why can't I describe std :: array as follows?

#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 } }; } 

When doing this, I get an error message:

error: too many initializers for std::array<Point, 3ul>

but it works as follows:

 std::array<Point, 3> m_points { Point{ 1.0f, 1.0f }, Point{ 2.0f, 2.0f }, Point{ 3.0f, 3.0f } }; 

Unlike std::map you can initialize both methods, 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}}; 
+5
source share
2 answers

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 curly braces, such as the initializer of the entire array (internal aggregate). std::array is a collection containing another collection.

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 the initializer of the next element of the internal aggregate.

Consider this simple demo program.

 #include <iostream> struct array { int a[10]; }; int main() { array a = { { 0, 0 }, { 1, 1 } }; return 0; } 

The compiler generates an error, for example

 prog.cpp:14:33: error: too many initializers for 'array' array a = { { 0, 0 }, { 1, 1 } }; ^ 

This means that { 0, 0 } is the initializer of the internal array (internal aggregate). Thus, the next initializer in curly brackets does not have the corresponding data element in the external population (structure).

+6
source

std::array does not have explicitly defined constructors, unlike other standard containers, such as std::vector or std::map , but only automatically provided constructors. Using std::vector compiler will try to match your expression with every constructor available and for a type construct

 std::vecor<Point> m_points { {1.0f,1.0f}, {2.0f,2.0f}, {3.0f,3.0f} }; 

finds match with constructor

 std::vector::vector(initializer_list<T>, const Allocator& = Allocator() ); 

But with std::array it should use the aggregate initialization of the base array ( Point[3] in your case), and therefore your design does not match. To make it work, you must add a couple more curly braces

 std::array<Point, 3> m_points { { { 1.0f, 1.0f }, { 2.0f, 2.0f }, { 3.0f, 3.0f } } }; 
+2
source

All Articles