合成移动构造函数的行为

时间:2017-09-27 11:50:44

标签: c++11 move

我正在阅读C ++ Primer第5版并遇到以下问题。该书列出了几种将合成移动操作定义为已删除的情况。其中之一是“与复制构造函数不同,如果类具有定义其自己的复制构造函数但不定义移动构造函数的成员,或者该类具有未定义的成员,则移动构造函数被定义为已删除它自己的复制操作,编译器无法合成移动构造函数。移动赋值也是如此。“ 并提供以下演示代码:

// assume Y is a class that defines its own copy constructor but not a move constructor
struct hasY {
    hasY() = default;
    hasY(hasY&&) = default;
    Y mem; // hasY will have a deleted move constructor
};
hasY hy, hy2 = std::move(hy); // error: move constructor is deleted

但是,对于gcc 7.2.1和clang-900.0.37,代码都是可运行的,这本书错了吗?

以下是完整的测试代码:

#include <iostream>

struct Y {
    Y() { std::cout << "Y()" << std::endl; }
    Y(const Y&) { std::cout << "Y(const Y&)" << std::endl; }
    //Y(Y&&) { cout << "Y(Y&&)" << endl; }
};

// assume Y is a class that defines its own copy constructor but not a move constructor
struct hasY {
    hasY() = default;
    hasY(hasY&&) = default;
    Y mem; // hasY will have a deleted move constructor
};

int main() {
    hasY hy, hy2 = std::move(hy); // error: move constructor is deleted
    return 0;
} 

1 个答案:

答案 0 :(得分:0)

本书正确描述了C ++ 11标准规定的行为。但是,从C ++ 14开始,规定的行为发生了变化,采用了Defect Report #1402 "Move functions too often deleted"

的分辨率