考虑以下代码:
struct foo {
std::vector<int> v;
foo(std::initializer_list<int> L) : v{L} {}
};
上面的代码编译正常,并按预期初始化v
。现在考虑以下代码:
struct bar {
std::array<int, 3> a;
bar(std::initializer_list<int> L) : a{L} {}
};
上面的代码会产生编译错误。
错误:没有可靠的转换来自&#39; std :: initializer_list&#39;到&#39; int&#39;
在网上搜索我发现&#34;正确&#34;使用std::array
初始化成员std::list_initializer
的方法是以下列方式使用reinterpret_cast
:
bar(std::initializer_list<int> L) : a(reinterpret_cast<std::array<int, 3> const&>(*(L.begin()))) {}
为什么我可以在构造函数的初始化列表中使用std::vector
初始化成员std::initializer_list
,但我不能成为成员std::array
?
上面的解决方法是使用reinterpret_cast
以std::array
初始化成员std::initializer_list
的正确方法吗?
答案 0 :(得分:5)
std::array
是designed (in the Boost library)以支持使用C ++ 03的大括号初始化语法。在C ++ 03中执行此操作的唯一方法是作为POD(普通旧数据)类型,一个没有构造函数。初始化程序列表在C ++ 11中与std::array
一起引入,但std::array
未从其Boost版本更改为使用初始化程序列表。所以,它是历史性的。
顺便提一下,请注意reinterpret_cast
在这里很危险,因为初始值设定项列表可能包含的项目少于array
。
答案 1 :(得分:1)
std::array
是一个围绕C ++数组的瘦包装器,看起来像
template<typename T, size_t N>
struct {
T data[N];
}
因此,没有任何构造函数可以处理std::initializer_list
,您必须坚持使用vector
或使用其他内容(如std::copy
)复制元素构造函数。
答案 2 :(得分:1)
foo(std::initializer_list<int> L) : v{L} {}
std::vector
有一个构造函数,它接受std::initializer_list
作为输入。因此,您正在初始化向量本身,而不是std::vector
的任何特定元素。
bar(std::initializer_list<int> L) : a{L} {}
std::array
没有接受std::initializer_list
作为输入的构造函数(事实上,它根本没有任何构造函数,只能通过aggregate initialization初始化)。因此,您正在尝试初始化数组的特定元素,这就是编译器抱怨它无法将std::initializer_list
转换为int
的原因。