`make_unique_for_overwrite` 仍然初始化 `std::pair` 元素

`make_unique_for_overwrite` still initializes `std::pair` elements

我希望

auto myPairs = make_unique_for_overwrite<pair<uint64_t, void*>[]>(arraySize);

会为我的 pair 提供未初始化的内存。无论如何,我稍后会覆盖那些,并且(不必要的)初始化目前负责我算法的 600 毫秒总运行时间中的 120 毫秒。

避免这种初始化的最惯用的方法是什么?

根据 cppreferencestd::pair 的默认构造函数总是对其元素进行值初始化(也称为零)。

解决办法是去掉pair。您可以将其替换为具有两个成员的结构。

I know I could still just allocate ... and then reinterpret_cast

尝试 reinterpret_cast 这样的结构 std::pair 会导致未定义的行为。

随心所欲

pair<uint64_t, void*>* myPairs = (pair<uint64_t, void*>*)malloc(sizeof(pair<uint64_t, void*>)*arraySize);

I was hoping that [make_unique_for_overwrite] would give me uninitialized memory for my pairs.

没有。您正在调用的重载将为 std::pair 的数组分配内存,然后 default-initialize each element, per https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique:

  1. Same as (2), except that the array is default-initialized. This overload participates in overload resolution only if T is an array of unknown bound. The function is equivalent to:

unique_ptr<T>(new std::remove_extent_t<T>[size])

所以,这个调用:

auto myPairs = make_unique_for_overwrite<pair<uint64_t, void*>>[]>(arraySize);

有效:

auto myPairs = unique_ptr<pair<uint64_t, void*>[]>(new pair<uint64_t, void*>[arraySize]);

std::pair的默认构造函数value-initializes its members, per https://en.cppreference.com/w/cpp/utility/pair/pair:

  1. Default constructor. Value-initializes both elements of the pair, first and second.
  • This constructor participates in overload resolution if and only if std::is_default_constructible_v<first_type> and std::is_default_constructible_v<second_type> are both true.
  • This constructor is explicit if and only if either first_type or second_type is not implicitly default-constructible.

因此,您实际上是在创建一个数组对,每个数组都初始化为 {0, nullptr},甚至在您更改以查看内存之前。

What is the most idiomatic way to avoid this initialization?

自己分配原始内存,然后根据需要placement-new其中的std::pair个元素。

或者使用 std::vector 并让它通过其 reserve() 方法为您处理。