我想初始化一个带有对象列表的向量或数组。它适用于矢量,但不适用于数组:
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有什么区别,这会阻止数组类型支持这种语法?
答案 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
(在您的示例中,这是一个数组,两个元素)