Sink参数实现赋值运算符和语言缺陷

时间:2014-08-22 09:50:47

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

在C ++现在的2012年会议的主题演讲中,Sean Parent介绍了“沉沦论证”的概念。他建议如果它们被函数“消耗”,则按值传递参数。然后移动或复制接收器参数,具体取决于其R值或L值。

他明确提到赋值运算符作为具有接收参数的操作的实例。

因此,他将此实现作为演讲中的一个例子:

object_t& operator = (object_t x)
{ object_ = move(x.object_); return *this;  }

在后来的会谈中,例如在Going Native 2013中,他重复了指南,但提到由于语言缺陷,需要实施单独的移动分配操作符:

这是他幻灯片中的引文:

  • 按值传递接收器参数并移动或交换到位。
  • 接收器参数是函数传递的任何参数。
    • 赋值的参数是一个接收器参数。
    • 但是,由于语言缺陷,您必须编写移动赋值运算符。

我搜索了有关此特定语言缺陷的信息但未找到任何信息。

  1. 任何人都可以解释这种语言缺陷是什么以及为什么使用接收器参数的赋值运算符不起作用。
  2. 这种语言缺陷会在C ++ 14中持续存在吗?
  3. 提前致谢, 勒夫

1 个答案:

答案 0 :(得分:3)

肖恩父母在他link的评论中回答了这个问题。


假设您有一个class Foo带有赋值运算符,如下例所示:

class Foo {
  Foo& operator=(Foo o) noexcept {
    member = move(o.member);
    return *this; 
  }
};

并将Foo对象包裹在struct中,例如struct wrap,如下例所示:

struct wrap { Foo m_ };

然后wrap将无法获得默认的移动分配。要使wrap获得默认noexcept移动分配,所有成员必须拥有noexcept移动分配 - 此确定是通过签名进行的。标准表示,wrap获取默认noexcept移动作业时,所有成员都必须拥有签名为T& operator=(T&&) noexcept的移动作业。

修复是重新定义需求,因此它表示如果所有成员都满足noexcept,结构或类将获得默认的is_nothrow_move_assignable<T>移动分配 - 以上情况。也就是说,我们希望根据概念或操作语义来定义需求,而不是在匹配精确签名方面。


相关问题