【问题标题】:Move-assignment and reference member移动分配和参考成员
【发布时间】:2013-12-27 08:56:02
【问题描述】:

对具有引用成员变量的类进行复制分配是禁忌,因为您无法重新分配引用。但是移动分配呢?我只是简单地尝试了moveing 它,但是当我只想移动引用本身时,这当然会破坏源对象:

class C
{
public:
    C(X& x) : x_(x) {}
    C(C&& other) : x_(std::move(other.x_)) {}
    C& operator=(C&& other)
    {
        x_ = std::move(other.x_);
    }
private:
    X& x_;
};

X y;
C c1(y);

X z;
C c2(z);

c2 = c1; // destroys y as well as z

我不应该只实施移动分配并坚持移动构造吗?这使得swap(C&, C&) 难以实现。

【问题讨论】:

  • 一般来说,如果一个人想用引用做一些不平凡的事情,难道不会使用reference_wrapper<T> 并完成它吗?我敢肯定,如果不是微不足道的话,移动构造函数和赋值就会变得微不足道(注意不是trivial)。
  • @LuisMachuca 这似乎有效。如果您将其添加为答案,我会投票赞成。谢谢。
  • 你有点错过x_的声明...
  • @ildjarn 哎呀!现在修好了。谢谢。
  • @thehouse - 注意到并完成,谢谢。

标签: c++ c++11 move-semantics


【解决方案1】:

(根据 OP 的建议作为评论的答案发布)

一般来说,如果想用 C++ 中的引用做一些重要的事情,可以使用reference_wrapper<T>,它本质上是T& 的一种花哨的价值语义替代品,那么可以使用它 - 它已经提供(重新)分配和其他操作。我敢肯定,如果不是微不足道的话,这将使移动构造函数和赋值几乎微不足道(注意不是trivial,如is_trivially_* 语义)。

“引用包装器”作为 TR1 的一部分添加到 C++03,并且是 C++11 的一部分。

文档:http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper

【讨论】:

  • 值得推广 cmets 以获得答案,这样我们就有更多可见的向上/向下投票按钮
  • reference_wrapper 是不可移动的,所以这并不能真正解决问题。据我所知,如果您希望您的类包含引用并且可以移动,则必须使用指针。
  • @Nemo 包含std::reference_wrapper 的类也可以有一个右值的复制构造函数/右值的赋值运算符,所以这不是回答原始问题吗?在上述情况下,它将允许您使用所有默认值,使用零规则。
【解决方案2】:

在某种意义上,引用是一个T *const,顶部带有句法糖,用于自动取消引用、自动捕获和自动生命周期扩展临时对象。 (请注意,这并不完全正确,但通常在实践和实用性中)

如果你想要一个可重新安装的引用,C++ 有这些:它们被称为指针。如果您愿意,可以使用访问器将取消引用替换为函数调用。难以模仿的其余功能(临时延长寿命)不适用于struct 成员。

【讨论】:

  • 指针的语义比可重新定位的引用要弱。例如,您可以将NULL 分配给他们。更重要的是,他们根本没有记录意图(写代码以被读取而不是执行等)。
猜你喜欢
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-03
  • 2013-11-14
  • 1970-01-01
  • 2014-11-12
相关资源
最近更新 更多