在构造函数的初始化列表中使用std :: initializer_list初始化std :: array

时间:2015-06-19 00:07:24

标签: c++ c++11 stl initializer-list stdarray

考虑以下代码:

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_caststd::array初始化成员std::initializer_list的正确方法吗?

3 个答案:

答案 0 :(得分:5)

std::arraydesigned (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的原因。