我有以下代码
class A {
public:
A(){}
~A(){}
private:
std::vector<std::unique_ptr<double> > x;
};
A f() {
A a;
return a;
}
int main() {
A a=f();
return 0;
}
它不编译(gcc 4.7),除非我注释掉析构函数。实际上,我的代码中并不需要这个析构函数,我只是想在调试时使用它。
然而,我不明白发生了什么,因此我担心我做错了什么。这是怎么回事?
这是因为显式定义的析构函数的存在阻止了为A
隐式生成move构造函数。
c++ 11标准第12.8/9段:
如果类X的定义没有显式声明move构造函数,则将隐式声明一个默认当且仅当
- X没有用户声明的复制构造函数
- X没有用户声明的复制赋值操作符
- X没有用户声明的move赋值操作符
- X没有用户声明的析构函数,并且
- move构造函数不会被隐式定义为删除。
现在没有move构造函数,为了从f()
返回值,编译器将尝试调用隐式生成的复制构造函数(为了向后兼容,它仍然在生成)。然而,std::unique_ptr
是不可复制的。因此,出现错误。
显式定义move构造函数(或者像juanchopanza在注释中建议的那样声明一个默认构造函数)将解决这个问题。