c++11 - 赋值运算符的汇参数实现及语言缺陷

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

在 2012 年 C++now 大会的主题演讲中,Sean Parent 介绍了“汇参数”的概念。他的建议是,如果参数被函数“消耗”,则按值传递参数。然后根据其 R 值或 L 值 move 或复制接收器参数。

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

因此他在演讲中以这个实现为例:

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

在以后的谈话中,例如在 Going Native 2013 上,他重复了指南,但提到由于语言缺陷,需要实现单独的 move 赋值运算符:

这是他幻灯片中的引文:

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

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

  1. 谁能解释一下这种语言缺陷是什么,以及为什么使用接收器参数的赋值运算符不起作用。
  2. 这种语言缺陷会在 C++14 中持续存在吗?

提前致谢, 约阿希姆

最佳答案

Sean Parents 在他的评论中回答了这个问题 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不会得到默认的 move 分配。对于 wrap获得默认 noexcept move 分配,所有成员必须有一个 noexcept move 分配——这个决定是通过签名做出的。那是标准说的 wrap获得默认 noexcept move 任务所有成员必须有签名为T& operator=(T&&) noexcept的 move 任务.

解决方法是重新表述要求,使其表示结构或类将获得默认值 noexcept如果所有成员都满足 is_nothrow_move_assignable<T>,则 move 分配- 以上就是这样做的。也就是说,我们希望根据概念或操作语义来定义需求,而不是根据匹配精确签名来定义需求。


关于c++11 - 赋值运算符的汇参数实现及语言缺陷,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25444201/

相关文章:

macos - 使用 Qt 构建时无法使用 C++11 功能

C++ - 在创建时调用赋值运算符而不是复制构造函数

c++ - 构造函数和 operator= 具有动态内存分配

r - 未找到前向箭头运算符

c++ - 关于 MSVC 和 g++ 处理 C++ 模板代码的区别

c++ - 根据另一个数组对一个数组进行排序

c++ - 复制和修改 std::strings 时无法解释的差异

c++ - 如何在类模板中有效地初始化 std::variant 数据成员

c++ - 在 std::move 之后使用对象不会导致编译错误

c++ - 在 C++ 中,对具有唯一 ID 的对象进行复制/move/分配的正确方法是什么?