0

考虑以下代码:

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

上面的代码给出了编译错误。

错误:没有从“std::initializer_list”到“int”的可行转换

在网上搜索我发现std::array用 a初始化成员的“正确”方法std::list_initializerreinterpret_cast按以下方式使用:

bar(std::initializer_list<int> L) : a(reinterpret_cast<std::array<int, 3> const&>(*(L.begin()))) {}

问:

为什么我可以在构造函数的初始化列表中使用 a 来初始化成员std::vectorstd::initializer_list但我不能成为成员std::array

上面显示的解决方法是用reinterpret_cast正确的方法初始化成员std::arraystd::initializer_list

4

3 回答 3

6

std::array设计为(在 Boost 库中)支持 C++03 的大括号初始化语法。在 C++03 中做到这一点的唯一方法是作为 POD(普通旧数据)类型,一种没有构造函数的类型。初始化器列表是在 C++11 中与 一起引入的std::array,但std::array并未从其 Boost 版本更改为使用初始化器列表。所以,这是历史性的。

顺便说一句,请注意reinterpret_cast这里很危险,因为初始化列表可能包含的项目少于array.

于 2015-06-19T00:12:45.857 回答
1

astd::array是一个 C++ 数组的薄包装器,看它像

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

因此它没有任何构造函数能够处理 a std::initializer_list,您必须坚持使用 avector或在构造函数中使用其他东西(如std::copy)复制元素。

于 2015-06-19T00:12:21.777 回答
1
foo(std::initializer_list<int> L) : v{L} {}

std::vector有一个接受 astd::initializer_list作为输入的构造函数。因此,您正在初始化向量本身,而不是std::vector.

bar(std::initializer_list<int> L) : a{L} {}

std::array没有接受 astd::initializer_list作为输入的构造函数(实际上它根本没有任何构造函数,只能通过聚合初始化来初始化)。因此,您试图初始化数组的特定元素,这就是编译器抱怨它无法将 a 转换为 astd::initializer_list的原因int

于 2015-06-19T00:17:15.447 回答