gpt4 book ai didi

c++ - std::launder、std::vector 和 move 仅可构造类型

转载 作者:行者123 更新时间:2023-11-30 01:35:30 32 4
gpt4 key购买 nike

对于 feature requesta project of mine ,我想/有人建议我使用 std::launder 在 vector 中移动元素,其中元素只能移动可构造(未定义移动赋值运算符)。
目标是将最后一个元素移动到给定位置 i,然后弹出前一个元素。

换句话说,生成的代码将是这样的(为此目的的简化版本):

void foo(std::vector<my_type> &vec, std::size_t i) {
my_type *el = vec.data() + i;
el->~my_type();
new (std::launder(el)) my_type{std::move(vec.back())};
vec.pop_back();
}

my_type 定义为:

struct my_type { const int v; };

使用 std::launder 的目的是为可能的优化设置一个障碍,因为 my_type 中的 v常量。因此,为了能够回收为 vec[i] 保留的内存,以便用不同的实例替换包含的对象(实际上,我理论上移动最后一项到不同的位置)。

这是一个有效的方法/解决方案还是仍然是 UB,因为如果我做了类似的事情而不重复 std::launder 就会发生这种情况?

据我所知,std::launder 的目的是允许用户做这样的事情,因此在我看来上面的代码片段是合法的。但如果我错了我也不会感到惊讶,所以我想得到比我更有经验的人的反馈

--- 编辑

同样,我也想交换到相同类型的元素。
生成的代码应该是这样的:

const auto tmp = std::move(vec[i]);
vec[i].~object_type();
new (std::launder(&vec[i])) object_type{std::move(vec[j])};
vec[j].~object_type();
new (std::launder(&vec[j])) object_type{std::move(tmp)};

我非常有信心,如果 std::launder 适合第一个示例,那么出于类似的原因,这个示例也应该适用。我错了吗?

最佳答案

launder 为您提供指向已存在对象的指针。

那里没有对象。您刚刚在上一行中销毁了它。

甚至调用 launder 本身也是纯粹的 UB。

对于这种事情,当您访问 新创建的对象时,需要launder。不是在您创建它时。

关于c++ - std::launder、std::vector 和 move 仅可构造类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53989927/

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