创建具有默认构造函数的未初始化项数组

Creating an uninitialized array of items which have default constructors?

本文关键字:初始化 数组 构造函数 默认 创建      更新时间:2023-10-16

给定一个类Foo,它具有一些值初始化默认构造函数:

class Foo {
private:
    uint32_t x;
public:
    constexpr Foo()
        : x { 3 }
    {}
    // ... and some other constructors
};

我需要分配这些Foo的数组。我不希望数组元素的默认构造函数运行,因为稍后我将显式初始化每个元素。像这样:

Foo foos[20000];
for (int i = 0; i < 20000; ++i) {
    foos[i] = init(i);
}

有没有办法获得这样一个未初始化的Foo数组,因为我们不允许将Foo的默认构造函数更改为非初始化的构造函数?

顺便说一下,这是您在 D 中创建未初始化数组的方式:

Foo[20000] foos = void;

。在 Rust 中也是如此:

let mut foos: [Foo; 20000] = unsafe { std::mem::uninitialized() };

如果使用 C++11 ,则可以使用 std::vectoremplace_back()

vector<Foo> foos;
for(int i = 0; i < 20000; ++i)
    foos.emplace_back( /* arguments here */);

也许这更准确地回答了手头的问题?

#include <type_traits>
class Foo {
private:
    uint32_t x;
public:
    constexpr Foo()
        : x { 3 }
    {}
    constexpr Foo(uint32_t n)
        : x { n * n }
    {}
};
    // ...and then in some function:
    typename std::aligned_storage<sizeof(Foo), alignof(Foo)>::type foos[20000];
    for (int i = 0; i < 20000; ++i) {
        new (foos + i) Foo(i);
    }

缺点似乎是您只能使用构造函数来初始化这些元素,而不能使用自由函数或其他任何东西。

问:然后我可以像这样访问这些Foo吗:

    Foo* ptr = reinterpret_cast<Foo*>(foos);
    ptr[50] = Foo();
您可能

正在寻找的是std::get_temporary_buffer

int main()
{
  size_t n = 20000;
  auto buf = std::get_temporary_buffer<Foo>(n);
  if (buf.second<n) {
    std::cerr << "Couldn't allocate enough memoryn";
    return EXIT_FAILURE;
  }
  // ...
  std::raw_storage_iterator<Foo*,Foo> iter(buf.first);
  for (int i = 0; i < n; ++i) {
    *iter++ = Foo();
  }
  // ...
  std::return_temporary_buffer(buf.first);
}