C++11 赋值运算符的Sink参数实现及语言缺陷

C++11 赋值运算符的Sink参数实现及语言缺陷,c++11,move-semantics,assignment-operator,C++11,Move Semantics,Assignment Operator,Sean Parent在2012年C++now大会上的重点演讲中介绍了“sink参数”的概念。他的建议是,如果参数被函数“消耗”,则按值传递参数。然后根据其R值或L值移动或复制sink参数 他明确提到赋值运算符是具有sink参数的操作的一个实例 因此,他在演讲中以这一实施为例: object_t& operator = (object_t x) { object_ = move(x.object_); return *this; } 在随后的会谈中,例如在2013年Gong Nati

Sean Parent在2012年C++now大会上的重点演讲中介绍了“sink参数”的概念。他的建议是,如果参数被函数“消耗”,则按值传递参数。然后根据其R值或L值移动或复制sink参数

他明确提到赋值运算符是具有sink参数的操作的一个实例

因此,他在演讲中以这一实施为例:

object_t& operator = (object_t x)
{ object_ = move(x.object_); return *this;  }
在随后的会谈中,例如在2013年Gong Native大会上,他重复了指南,但提到由于语言缺陷,需要实施单独的移动分配操作员:

这是他幻灯片中的引文:

  • 为每个值传递接收器参数,并将其移动或交换到位
  • sink参数是函数传递的任何参数。
    • 赋值的参数是sink参数
    • 但是,由于语言缺陷,必须编写移动分配运算符
我搜索了关于这个特定语言缺陷的信息,但没有找到任何信息

  • 谁能解释一下这种语言缺陷是什么,以及为什么使用sink参数的赋值运算符不起作用
  • 这种语言缺陷会在C++14中持续存在吗
  • 提前感谢,,
    约阿希姆(Joachim)

    肖恩(Sean)的父母在他的评论中回答了这个问题


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

    class Foo {
      Foo& operator=(Foo o) noexcept {
        member = move(o.member);
        return *this; 
      }
    };
    
    struct wrap { Foo m_ };
    
    并将
    Foo
    对象包装在
    struct
    中,比如说
    struct wrap
    ,如下例所示:

    class Foo {
      Foo& operator=(Foo o) noexcept {
        member = move(o.member);
        return *this; 
      }
    };
    
    struct wrap { Foo m_ };
    
    然后,
    wrap
    将不会获得默认移动分配。对于
    wrap
    要获得默认的
    noexcept
    move分配,所有成员都必须具有
    noexcept
    move分配-此确定通过签名进行。这就是标准,对于
    wrap
    要获得默认的
    noexcept
    移动分配,所有成员都必须具有签名为
    T&operator=(T&&)noexcept
    的移动分配

    修复方法是重新表述需求,使其表明,如果所有成员都满足
    is nothrow\u move\u assignable
    ,则结构或类将获得默认的
    noexcept
    移动分配,而上述操作就是如此。也就是说,我们希望根据概念或操作语义来定义需求,而不是根据匹配精确签名来定义需求