为什么大括号括起的初始化列表不适用于std :: array

时间:2017-02-06 21:54:38

标签: 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 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;
}

来自clang的错误:

widget.cpp:36:9: error: excess elements in struct initializer
        {"aw2", {1,2,3}} };
        ^~~~~~~~~~~~~~~~
widget.cpp:41:10: error: no viable conversion from 'const char [4]' to 'Object'
        {"ao1", {1,2,3}},
         ^~~~~
widget.cpp:41:17: error: no matching constructor for initialization of 'Object'
        {"ao1", {1,2,3}},
                ^~~~~~~

vector和array有什么区别,这会阻止数组类型支持这种语法?

2 个答案:

答案 0 :(得分:4)

这是一个有效的解决方案 - 您需要为数组提供双括号。

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

为什么?

http://en.cppreference.com/w/cpp/container/array

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

理论实施(实际上更复杂)

template <typename T, size_t size> 
struct array  
{
  T data[size]; 
}

所以第一个支撑是自己聚合初始化数组对象,第二个支撑聚合初始化内部“遗留C风格”数组。

答案 1 :(得分:0)

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

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

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

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

相关问题