C++ 为什么括号内的初始值设定项列表不适用于std::array

C++ 为什么括号内的初始值设定项列表不适用于std::array,c++,c++11,C++,C++11,我想用对象列表初始化向量或数组。它适用于向量,但不适用于数组: struct Widget { string name; vector<int> list; }; struct Object { string name; vector<int> list; Object(string _name, vector<int> _list) : name(_name), list(_list) { } }; int mai

我想用对象列表初始化向量或数组。它适用于向量,但不适用于数组:

struct Widget
{
    string name;
    vector<int> list;
};

struct Object
{
    string name;
    vector<int> list;
    Object(string _name, vector<int> _list) : name(_name), list(_list) { }
};

int main()
{
    const vector<Widget> vw = {
        {"vw1", {1,2,3}},
        {"vw2", {1,2,3}} };
    const array<Widget,2> aw = {
        {"aw1", {1,2,3}},
        {"aw2", {1,2,3}} };
    const vector<Object> vo = {
        {"vo1", {1,2,3}},
        {"vo2", {1,2,3}} };
    const array<Object,2> ao = {
        {"ao1", {1,2,3}},
        {"ao2", {1,2,3}} };
    return 0;
}

向量和数组之间的区别是什么,它阻止了数组类型支持这种语法?

这里是有效的解决方案-数组需要双大括号

int main()
{
    const vector<Widget> vw = {
        {"vw1", {1,2,3}},
        {"vw2", {1,2,3}} };
    const array<Widget,2> aw = {{
        {"aw1", {1,2,3}},
        {"aw2", {1,2,3}} }};
    const vector<Object> vo = {
        {"vo1", {1,2,3}},
        {"vo2", {1,2,3}} };
    const array<Object,2> ao = {{
        {"ao1", {1,2,3}},
        {"ao2", {1,2,3}} }};
    return 0;
}
intmain()
{
常数向量vw={
{vw1',{1,2,3},
{vw2',{1,2,3}};
常量数组aw={{
{“aw1”{1,2,3},
{“aw2”,{1,2,3}};
常数向量vo={
{vo1',{1,2,3},
{“vo2”,{1,2,3}};
常量数组ao={{
{ao1',{1,2,3},
{“ao2”,{1,2,3}};
返回0;
}
为什么?

数组是封装固定大小数组的容器。 此容器是一个聚合类型,其语义与将C样式数组T[N]作为其唯一非静态数据成员的结构相同。与C样式数组不同,它不会自动衰减为t*。作为聚合类型,最多可以使用N个可转换为T:std::array a={1,2,3};的聚合初始化器对其进行初始化

理论实施(现实中更为复杂)

模板
结构数组
{
T数据[大小];
}

因此,第一个大括号用于单独聚合初始化数组对象,第二个大括号用于聚合初始化内部“传统C样式”数组。

向示例中添加另一对大括号将使它们能够正常工作:

int main()
{
    const std::array<Widget,2> aw = {
        {
            {"aw1", {1, 2, 3}},
            {"aw2", {1, 2, 3}}
        }
    };

    const std::array<Object, 2> ao = {
        {
            {"ao1", {1, 2, 3} },
            {"ao2", {1, 2, 3} }
        }
    };

    cout << aw[0].name << " " << aw[1].list[1] << endl;
    cout << ao[0].name << " " << ao[1].list[1] << endl;

    return 0;
}
需要额外的一对大括号,因为
std::array
本身没有构造函数,只是使用聚合初始化而不是列表初始化


就实现而言,
std::array
由一个内部项组成,它是
N
元素的真正底层数组。因此,我们需要额外的大括号,因此我们使用one元素(在您的示例中,这是一个由两个元素组成的数组)初始化
std::array

我不是100%确定,但我相信这是聚合初始化和大括号内的初始化器列表之间的奇怪交互。它可以按照下面的答案来解决,但我不确定问题的具体原因是什么。仔细检查错误消息表明,由于缺少更好的术语,数组正在“吸收”一个额外的括号;请注意它是如何认为
“ao1
{1,2,3}
是两个不同的
对象
而不是同一
对象的初始化列表的一部分。这很有趣。这些是很多大括号…但是写的东西很有意义。链接的问题/答案也有帮助。谢谢!
template <typename T, size_t size> 
struct array  
{
  T data[size]; 
}
int main()
{
    const std::array<Widget,2> aw = {
        {
            {"aw1", {1, 2, 3}},
            {"aw2", {1, 2, 3}}
        }
    };

    const std::array<Object, 2> ao = {
        {
            {"ao1", {1, 2, 3} },
            {"ao2", {1, 2, 3} }
        }
    };

    cout << aw[0].name << " " << aw[1].list[1] << endl;
    cout << ao[0].name << " " << ao[1].list[1] << endl;

    return 0;
}
aw1 2
ao1 2