gpt4 book ai didi

c++ - move 语义不完整吗?

转载 作者:可可西里 更新时间:2023-11-01 15:52:05 26 4
gpt4 key购买 nike

在复制效率低下的情况下, move 语义取代了复制语义。复制语义完全处理可复制对象,包括 const 对象。

在 c++11 中已经存在无数不可复制的对象,例如 std::unique_ptr。这些对象完全依赖于 move 语义,因为从一个对象 move 允许使它无效。这对于像 RAII 这样的流行设计模式很重要(恕我直言)。

将 const 不可复制对象分配给内存区域时会出现问题。这样的对象无法以任何方式恢复。

这在对象的生命周期中显然很重要,因为它是常量。然而,在它的生命周期结束时,当调用析构函数时,(不存在的)对象暂时是非常量的。

我建议 move 析构函数可能是 move 语义模型的一个有值(value)的补充。

考虑一个简单的情况,其中在 unordered_set 中使用了 unique_ptr。您可以使用 move 构造函数(或构造“emplace”)插入到此集合中,但是如果您想将此指针 move 到另一个 unordered_set(即保持常量),这是不可能的。

本质上,有一个iterator insert((possibly const) key&&)但是没有const key&& erase(iterator)。事实上这是不可能的。容器只能被扩展以返回一些指向键的指针,忘记它吧。

一个 move 的析构函数可以解决这个问题,即 const MyClass&& ~MyClass(),因为它只会在析构期间违反 const(当编译器认为该对象无论如何都无效时)。

编辑:我应该指出const MyClass&& ~MyClass() const 实际上更有意义。析构函数不必修改任何内容,只需销毁对象,就好像它不再是它控制的任何资源的有效句柄一样。

最佳答案

恕我直言,您已经确定了真正的需求。

您的解决方案听起来很像我所说的破坏性 move 语义original move semantics proposal 中描述了这种可能性.我认为这样的设计是可能的,尽管它并非没有问题。据我所知,标准委员会中没有人从事这一领域的工作。

有更简单的方法可以从不需要更改语言的关联容器中提取仅 move 类型(除了可能允许类型双关而没有未定义的行为)。

N3645是一个仅限库的提案,它将嵌套的 node_ptr 类型放入每个容器中。 node_ptr 很像 unique_ptr。它对关联容器中的节点具有唯一所有权。但是,当您取消引用它时,您可以非常量访问节点中的 value_type,而不是节点本身。 extractinsert 成员被添加到关联容器中,允许将节点(由 node_ptr 拥有)插入容器或从容器中删除。

您可以使用它从容器中删除一个节点,然后将一个只能 move 的类型移出该节点,并让 ~node_ptr() 在您完成操作后清理该节点它。本文包括这个示例来演示此功能:

set<move_only_type> s;
s.emplace(...);
move_only_type mot = move(*s.extract(s.begin())); // extract, move, deallocate node

请注意 s.extractnoexcept,当然 ~node_ptr() 也是。如果move_only_type的 move 结构是noexcept,那么整个操作就是noexcept。否则,如果 move 构造抛出,set 将被保留,就好像该项目已从 set 中删除一样。

目前,N3645 没有任何进展.它尚未投票成为工作草案,而且我不相信它会成为工作草案。

更新 C++17

我的观点是正确的:我上面描述的功能已通过 P0083R3 投票到 C++17 中.感谢 Cosme 在下面的评论中提醒我这一点。

关于c++ - move 语义不完整吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21085735/

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