繁体   English   中英

移动 unique_ptr 的内容

[英]moving the content of a unique_ptr

所以如果我有一个可移动的 (rval) std::unique_ptr,我可以使用简单的赋值来移动内容而不是复制吗? (指向object的内容,而不是指向它的指针)

看起来我做不到,但是“也许我做错了”?

如果不是,不允许这样做的理由是什么?

细节:

所以我已经成为 class 的所有者,其方法是从 Hell 返回 std::map,我真的不想在所有使用 /my/ class 的地方包含 hell.h,只是在少数几个真正使用的地方想go那里。

所以我的想法是改变方法的返回签名

#include "hell.h"
std::map<std::string, Hell> CopyTheObjectSpecified(...);

class Hell;
std::unique_ptr<std::map<std::string, Hell>> CopyTheObjectSpecified(...);

而且,对于 new 和 delete 的成本,我现在不需要详细说明 Hell,除非调用该方法,并且该代码将安全地由 unique_ptr 限定范围。 鉴于 map 副本有很多分配,我不关心多一个。

(ben-v 建议我在 Hell 周围建立一个编译防火墙 - 看它的好方法)

但是,其中一位来电者正在做:

void Angel(std::map<std::string, Hell>& hell)
{
  hell = CopyTheObjectSpecified(...);
}

用于减少移动分配(甚至是完整的返回复制省略 - 可能不是)

所以现在我正在做一个

void Angel(std::map<std::string, Hell>& hell)
{
  hell = * CopyTheObjectSpecified(...);
}

或者更冗长,视觉上令人反感,但几乎可以在任何地方跟踪和注射:

void Angel(std::map<std::string, Hell>& hell)
{
  hell = CopyTheObjectSpecified(...) .get()[0] ;
}

在我看来,查看调试, *get()的重载似乎没有看出 unique_ptr 是一个 r-val,因此内容也应该作为 r-val 返回。

(请注意,我在这里的意图是 rval unique_ptr 实例继续拥有它指向的 object,并且当它正常离开 scope 时将删除它,但是 object 将通过移动剥离其内容。)

所以这是调用复制/删除语义而不是移动语义,这是一种开销。 我不能让代码运行得更慢!

当然,我可以简单地添加一个 std::move(),但是当原作者取回它时,那将是一种额外的味道。 我仍然看到“未封装”的 std::move 作为气味。 也许最终我会习惯看到它。

void Angel(std::map<std::string, Hell>& hell)
{
  hell = std::move( * CopyTheObjectSpecified(...) ) ;
}

或者使用交换操作(感谢 Ben Voigt)

void Angel(std::map<std::string, Hell>& hell)
{
  hell.swap ( * CopyTheObjectSpecified(...) ) ;
}

(是的,CopyTheObjectSpecified() 的最佳(目前)实现是实际制作并返回一个副本,而不是返回一些对不断变化的数据的 shared_ptr const 引用)

或者我可以将可移动性最低限度地封装在 unique_ptr 的包装器 class 中。 使用 when-rval-content-movable unique_ptr 有危险吗?

目前我们编码为 c++11。也许我需要后期标准的帮助才能正确执行此操作? 但这可能会帮助我制定一个可读和可转移的解决方案。

呃。 我只想要 /my/ 类的 /out/ 这个方法! 但今天这不是一个选择。

在最简单的层面上,似乎不需要 unique_ptr,因为std::map可以在不完整的类型上实例化就好了。 所以你可以这样做:

class Hell;
std::map<std::string, Hell> CopyTheObjectSpecified(...);

并且您只需要 #include 代码即可将某些内容放入 map 或将其从 map 中取出(或复制/复制整个地图)。 std::map已经包含一个间接级别,这意味着它可以在不知道键/值类型的细节的情况下移动。

所以

void Angel(std::map<std::string, Hell>& hell)
{
  hell = CopyTheObjectSpecified(...);
}

应该继续工作就好了。

我不确定我的回答是否有帮助,但据我所知,创建unique_ptr意味着 object 的所有权无法更改,这意味着它仅在已定义的 scope 中有效/创建所以我认为你不能移动它的内容,因为它会改变所有权。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM