如何在没有默认构造函数的情况下初始化类的 std::array ?

Mat*_*att 2 c++ arrays constructor stl initializer-list

假设我有一个没有名为 的默认构造函数的类Foo

如果我使用std::vector,我可以这样做:

std::vector<Foo> vec(100, Foo(5));
Run Code Online (Sandbox Code Playgroud)

这将创建一个包含 100 个元素的向量,每个元素都有值Foo(5)

我该如何做同样的事std::array<Foo, 100>

我显然不想Foo(5)在初始化列表中显式列出 100 次。但我不能等到数组构造完成后才对其进行初始化,因为缺少默认构造函数将产生编译器错误。

通过提供类似于“placement new”或函数的显式构造函数参数,该解决方案还允许我避免复制构造函数emplace

Igo*_*nik 7

使用复制构造函数,可以执行以下操作:

template <typename T, size_t... Is>
std::array<T, sizeof...(Is)> MakeArrayHelper(
    const T& val, std::index_sequence<Is...>) {
  return {(static_cast<void>(Is), val) ...};
}

template <typename T, size_t N>
std::array<T, N> MakeArray(const T& val) {
  return MakeArrayHelper<T>(val, std::make_index_sequence<N>{});
}

std::array<Foo, 100> arr = MakeArray<Foo, 100>(Foo(5));
Run Code Online (Sandbox Code Playgroud)

实际上,这完全可以在没有复制构造函数的情况下完成。该解决方案严重依赖于 C++17 的强制复制省略。

template <typename T, size_t... Is, typename... Args>
std::array<T, sizeof...(Is)> MakeArrayHelper(
    std::index_sequence<Is...>, Args&&... args) {
  return {(static_cast<void>(Is), T{std::forward<Args>(args)...}) ...};
}

template <typename T, size_t N, typename... Args>
std::array<T, N> MakeArray(Args&&... args) {
  return MakeArrayHelper<T>(std::make_index_sequence<N>{},
                            std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)

演示