Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果一个类有一个成员具有copy ctor,但没有mov ctor,是否会导致包含该成员的类也使用deleted move ctor定义? 在C++ 5版ED中,我没有理解这一点:_C++_C++11_Move Semantics - Fatal编程技术网

如果一个类有一个成员具有copy ctor,但没有mov ctor,是否会导致包含该成员的类也使用deleted move ctor定义? 在C++ 5版ED中,我没有理解这一点:

如果一个类有一个成员具有copy ctor,但没有mov ctor,是否会导致包含该成员的类也使用deleted move ctor定义? 在C++ 5版ED中,我没有理解这一点:,c++,c++11,move-semantics,C++,C++11,Move Semantics,例如,假设Y是一个定义自己的复制构造函数但不定义自己的移动构造函数的类: //假设Y是定义自己的复制构造函数而不是移动构造函数的类 struct-hasY{ hasY()=默认值; hasY(hasY&&)=默认值; Y mem;//hasY将有一个已删除的移动构造函数 }; hasY hy,hy2=std::move(hy);//错误:已删除移动构造函数 编译器可以复制Y类型的对象,但不能移动它们。显式地初始化hasY 请求了一个移动构造函数,编译器无法生成该构造函数。因此,草率 将获得一个已

例如,假设Y是一个定义自己的复制构造函数但不定义自己的移动构造函数的类:

//假设Y是定义自己的复制构造函数而不是移动构造函数的类

struct-hasY{
hasY()=默认值;
hasY(hasY&&)=默认值;
Y mem;//hasY将有一个已删除的移动构造函数
};
hasY hy,hy2=std::move(hy);//错误:已删除移动构造函数

编译器可以复制Y类型的对象,但不能移动它们。显式地初始化hasY 请求了一个移动构造函数,编译器无法生成该构造函数。因此,草率 将获得一个已删除的移动构造函数。草率地遗漏了其行动的声明 构造函数,则编译器根本不会合成hasY-move构造函数。 如果移动操作被定义为 删除

所以我定义了
Y
,正如他所说:

struct Y
{
    Y() = default;
    Y(const Y&){std::cout << "Y's Copy-ctor\n";
    Y& operator=(const Y&){std::cout << "Y's copy-assignment operator\n"; return *this;}

};

struct hasY {
    hasY() = default;
    hasY(hasY&&) noexcept = default;
    Y mem; // hasY will have a deleted move constructor
};
  • 但是程序运行良好,没有像他说的那样抱怨删除了移动构造函数
输出:

Y's copy ctor
  • 正如您所看到的,尽管我已经在许多具有不同版本和不同编译标志的编译器上测试了该程序,但我的程序运行良好。我想这是书中的一个错误

  • 我认为类
    hasY
    是可移动的,其移动构造函数不会被删除,因为该移动构造函数调用隐式未定义(未删除但未定义)的类Y的移动构造函数,所以它会使用Y的复制构造函数,所以我认为类Y可以通过其复制构造函数移动。因此,程序会删除Y的副本

**参考文献中说:

如果满足以下任一条件,则类T的隐式声明或默认移动构造函数定义为已删除:

T具有无法移动的非静态数据成员(具有已删除、不可访问或不明确的移动构造函数); T具有无法移动的直接或虚拟基类(已删除、不可访问或不明确的移动构造函数); T具有直接基类或虚拟基类,且具有已删除或不可访问的析构函数

T是一个类似于并集的类,有一个带有非平凡移动构造函数的变量成员

T有一个非静态的数据成员,或者一个直接的或虚拟的基,而没有一个移动构造函数,这个构造函数是不可复制的

重载解析将忽略已删除的隐式声明的移动构造函数(否则将阻止从右值进行复制初始化)

  • 我在“隐式定义为已删除操作”和“根本未定义”之间也有歧义?对我来说,被定义为“已删除”就好像是在写:

    Y(Y&&) = delete; // generated by the compiler
    
而完全没有定义是表达的相同含义

***为了证实我的说法,类
hasY
的移动构造函数没有被删除,这里有一个简单的例子:

struct hasY {
    hasY() = default;
    hasY(hasY&&) noexcept = default;
    Y mem; // hasY will have a deleted move constructor
    std::unique_ptr<int> upi; // This really causes hasY non-copy-able
};
struct-hasY{
hasY()=默认值;
hasY(hasY&&)noexcept=默认值;
Y mem;//hasY将有一个已删除的移动构造函数
std::unique_ptr upi;//这确实会导致不可复制
};
  • 正如您所看到的,我添加了一个uniqe_ptr类型的不可复制对象,以防止hasY的复制,并且该程序像以前一样运行,没有erorrs,这意味着hasY的移动构造函数不会被删除

hasY
没有移动构造函数,但它有一个复制构造函数,因此编译器复制对象而不是移动它。@RaymondChen:你确定吗?对不起,误读了。我认为有一个
hasY(hasyconst&)=default但是没有。这本书是错误的(正如你自己所证明的)。没有移动构造函数与删除移动构造函数不同。这是否回答了您的问题?
struct hasY {
    hasY() = default;
    hasY(hasY&&) noexcept = default;
    Y mem; // hasY will have a deleted move constructor
    std::unique_ptr<int> upi; // This really causes hasY non-copy-able
};