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

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

本文关键字:std 初始化 数组 initializer list 构造函数 列表      更新时间:2023-10-16

考虑以下代码段:

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::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的正确方法吗?

std::array

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

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

std::array是围绕C++数组的薄包装器,如下所示

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

所以它没有任何能够应对std::initializer_list的构造函数,你必须坚持使用vector或在构造函数中使用其他东西(如std::copy)复制元素。

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作为输入的构造函数(实际上,它根本没有任何构造函数,只能通过聚合初始化进行初始化)。 因此,您正在尝试初始化数组的特定元素,这就是为什么编译器抱怨它无法将std::initializer_list转换为int的原因。