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

Initialization of std::array with std::initializer_list in constructor's initialization list

考虑以下代码:

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

上面这段代码编译报错

error: no viable conversion from 'std::initializer_list' to 'int'

在网上搜索我发现 "proper" 使用 std::list_initializer 初始化成员 std::array 的方法是按以下方式使用 reinterpret_cast

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

问:

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

上面显示的 reinterpret_cast 变通方法是否是使用 std::initializer_list 初始化成员 std::array 的正确方法?

a std::array 是一个围绕 C++ 数组的薄包装器,看起来像

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

因此它没有任何构造函数能够处理 std::initializer_list,您必须坚持使用 vector 或使用其他内容(例如 std::copy)复制元素构造函数。

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

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

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.

的原因