自动生成移动操作的规则是什么? [英] What are the rules for automatic generation of move operations?

查看:115
本文介绍了自动生成移动操作的规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 98中,C ++编译器可以通过成员自动拷贝自动生成拷贝构造函数和拷贝赋值运算符,例如

  struct X {
std :: string s;
std :: vector< int> v;
int n;
};

编译器自动为<$ c生成拷贝构造函数和拷贝赋值运算符



但是,如何在C ++ 11中使用移动语义来改变?



移动 构造函数 移动 / strong>自动生成 分配运算符 如果有复制构造函数和复制赋值运算符?



解决方案

从标准Ch。 12 - 特殊成员功能



Par 12.8 复制和移动类对象(强调我)


9。如果X类的定义没有明确声明一个移动构造函数,则当且仅当



时,才会默认声明为默认值。没有用户声明的副本构造函数,



- X没有用户声明的副本赋值运算符,



- X没有用户声明的移动赋值运算符,



- X没有用户声明的析构函数。



[注意:当移动构造函数没有被隐式声明或显式提供时,
否则会调用move构造函数的表达式可以调用一个拷贝构造函数。 -end note]


然后 11 说明删除默认行动的规则构造函数


11。隐式声明的复制/移动构造函数是其类的内联公共成员。 如果X具有以下内容,则类X的默认复制/移动构造函数定义为已删除(8.4.3):



一个非平凡的相应构造函数,X是一个类似union的类,



- 类型为M(或其数组)的非静态数据成员, / move,因为应用于M的相应构造函数的重载分辨率(13.3)导致了默认构造函数中被删除或无法访问的模糊度或函数。



不能被复制/移动的直接或虚拟基类B,因为应用于B的相应构造函数的重载分辨率(13.3)导致模糊度或被默认构造函数删除或不可访问的函数,



- 具有从默认构造函数中删除或无法访问的析构函数的类型的任何直接或虚拟基类或非静态数据成员,或



- 对于复制构造函数,是右值引用类型的非静态数据成员。默认的移动构造函数定义为已删除,被重载解析(13.3,13.4)忽略。



[注意:删除的移动构造函数会干扰从右值初始化它可以使用复制构造函数。 -end note]







复杂性全部*



这些规则可能有点难以控制。使用某种技术绕过复杂性是件好事。示例为:


  1. 利用零规则,以简化大多数类的写作。

  2. (隐式删除)显式地默认所讨论的特殊成员函数;

*自己的评论中提出的点数1)和 dyp (2)


In C++98, the C++ compiler could automatically generate copy constructor and copy assignment operator via member-wise copy, e.g.

struct X {
    std::string s;
    std::vector<int> v;
    int n;
};

The compiler automatically generates copy constructor and copy assignment operator for X, using member-wise copy.

But how do things change in C++11 with move semantics?

Are the move constructor and move assignment operator automatically generated, like copy constructors and copy assignment operators?

Are there cases in which move operations are not automatically generated?

解决方案

From the standard Ch. 12 - Special member functions

Par 12.8 Copying and moving class objects (emphasis mine)

9 . If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

— X does not have a user-declared copy constructor,

— X does not have a user-declared copy assignment operator,

— X does not have a user-declared move assignment operator, and

— X does not have a user-declared destructor.

[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. —end note ]

Then 11 explains the rules for deleting the defaulted move constructor

11 . An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/ move constructor for a class X is defined as deleted (8.4.3) if X has:

— a variant member with a non-trivial corresponding constructor and X is a union-like class,

— a non-static data member of class type M (or array thereof) that cannot be copied/moved because overload resolution (13.3), as applied to M’s corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,

— a direct or virtual base class B that cannot be copied/moved because overload resolution (13.3), as applied to B’s corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,

— any direct or virtual base class or non-static data member of a type with a destructor that is deleted or inaccessible from the defaulted constructor, or,

— for the copy constructor, a non-static data member of rvalue reference type. A defaulted move constructor that is defined as deleted is ignored by overload resolution (13.3, 13.4).

[ Note: A deleted move constructor would otherwise interfere with initialization from an rvalue which can use the copy constructor instead. —end note ]


On the complexity of it all *

The rules can be somewhat overwhelming. It's good to use some technique to bypass the complexity. Examples are :

  1. Make use of the rule of zero to simplify the writing of the majority of your classes.
  2. (On implicitly deleted) Explicitly default the special member function in question; if it would have been implicitly defined as deleted, the compiler will complain.

* points made in the comments by myself (1) and dyp (2)

这篇关于自动生成移动操作的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆