Difference between std::vector and std::array initializer lists

拟墨画扇 提交于 2019-12-05 05:46:47

See cppreference's section on aggregate initialization.

The effects of aggregate initialization are:

  • Each array element or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.

  • If the initializer clause is a nested braced-init-list, the corresponding class member is itself an aggregate: aggregate initialization is recursive.

This means that if you had an aggregate inside your struct, such as:

struct str {
    struct asdf
    {
        int first, last;
    } asdf; 
};

asdf would be initialized by the first nested brace-init-list, i.e. { { 1, 2 } }. The reason why you generally need two pairs of braces is because the nested brace-init-list initializes the underlying aggregate in std::array (for example, T a[N]).

However, you can still initialize your array like this:

array<str,3> fields {
    1, 2, 3, 4, 5, 6
};

or:

array<str,3> fields { {
    1, 2, 3, 4, 5, 6
} };

instead.

On the other hand, how you initialize your vector is covered by list initialization. std::vector has a constructor that accepts an std::initializer_list.

The effects of list initialization of an object of type T are:

  • Otherwise, the constructors of T are considered, in two phases:

    • All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list

Note that you wouldn't be able to initialize your vector ( like this:

vector<str> fields {
    1,2, 3,4, 5,6
};

but:

vector<int> fields {
    1,2, 3,4, 5,6
};

is perfectly fine.

It's because array initialization is built a bit different from vector.
To initialize an array you need to use two braces.
Because of a syntax feature you can skip it if you initialize just one object.
So the following is ok:

array{1,2,3} -> array{{1,2,3}}

But in your example you initialize multiple objects so the compiler doesn't add additional braces. Using two braces fixes that.

array<str,3> fields {{
    {1,2}, {3,4}, {5,6}
}};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!