gpt4 book ai didi

c++ - 移动到未初始化的内存,或者 raw_storage_iterator 是如何工作的

转载 作者:可可西里 更新时间:2023-11-01 16:36:49 28 4
gpt4 key购买 nike

我想将一系列对象移动到未初始化的内存中(使用移动构造)。由于 std::uninitialized_copy 没有 move-counterpart,我想到了两个选项:使用 std::moveraw_storage_iterator,或求助于手动循环:

T* dest = get_memory();
// option one
std::move(first, last, std::raw_storage_iterator<T*, T>(dest));
// option two
for (auto i=first; i != last; ++i, ++dest)
{
new(dest) T(std::move(*i));
}

第一个选项会执行移动构造(因此等同于第二个),还是复制构造,或默认构造后跟移动赋值?是否有其他考虑因素来选择一种或另一种选择?

最佳答案

std::raw_storage_iterator 中的赋值中使用 placement-new 运算符根据采用 const 左值引用的复制赋值运算符定义:

§ 20.7.10 [存储迭代器]/p1:

raw_storage_iterator& operator=(const T& element);

它总是调用复制构造函数(即使使用右值调用)。

此案例已报告为 LWG issue 2127它通过引入另一个采用右值引用的赋值运算符来增加对可移动构造类型的支持,这意味着一旦提议的更改被采用,它可能将移动构造元素移动到未初始化的内存中。在更新发生之前,您需要依赖自己的 for 循环。或者,您可以利用 std::uninitialized_copy算法定义如下:

§ 20.7.12.2 [uninitialized.copy]/p1:

for (; first != last; ++result, ++first)
::new (static_cast<void*>(&*result))
typename iterator_traits<ForwardIterator>::value_type(*first);

使用 std::make_move_iterator 包装输入迭代器后辅助函数,您将获得与手写 for 循环相同的效果:

std::uninitialized_copy(std::make_move_iterator(first)
, std::make_move_iterator(last)
, dest);

通过引入 std::uninitialized_move 扩展算法集:

std::uninitialized_move(first, last, dst);

关于c++ - 移动到未初始化的内存,或者 raw_storage_iterator 是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31495750/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com