英文:
Will compiler still generate default move constructor if I declare a deconstructor but exactly as same as the default deconstructor?
问题
我对于在这种情况下默认函数生成规则感到困惑:
对于最简单的类:
class B{};
它会自动生成移动构造函数。
然而,如果是这样的情况:
class B{
public:
~B(){}
}
我认为它应该与默认析构函数相同,那么此时会有默认的移动构造函数吗?如何检查呢?
class A{
public:
A() {}
A(const A& lv) {cout << "a copy ctor." << endl;}
A(A&& rv) {cout << "a move ctor." << endl;}
};
class B{
public:
//~B(){}
private:
A a;
};
int main()
{
B b;
B b2(std::move(b));
return 0;
}
我尝试了这种方法,似乎答案是否定的,但我不太确定。
英文:
I'm confused of the rules of default function generation at this situation:
For the simplest class:
Class B{};
It will auto-generated the move constructor.
However, what if for
Class B{
public:
~B(){}
}
I think it should be as same as the default deconstructor, will I have a default move constructor at this time? and how could I check it?
class A{
public:
A() {}
A(const A& lv) {cout << "a copy ctor." << endl;}
A(A&& rv) {cout << "a move ctor." << endl;}
};
class B{
public:
//~B(){}
private:
A a;
};
int main()
{
B b;
B b2(std::move(b));
return 0;
}
I tried this method, it seems the answer is no, but I'm not sure.
答案1
得分: 5
短答案是"不"。
更详细的答案是,重要的不是析构函数体的内容,而是它是否由用户声明。具体来说(参考N4950,[class.copy.ctor]/8):
如果类X的定义没有明确声明移动构造函数,那么只有在以下条件下,才会隐式声明一个非显式的移动构造函数:
- X没有用户声明的复制构造函数,
- X没有用户声明的复制赋值运算符,
- X没有用户声明的移动赋值运算符,
- X没有用户声明的析构函数。
所以,即使您将析构函数定义为与编译器默认生成的相同,您仍然已经声明了它,这样它就成为了用户声明的析构函数,编译器不再隐式生成移动构造函数(也不会生成移动赋值运算符)。
英文:
The short answer is "no".
The longer answer is that what matters isn't the content of the body of the dtor, but whether it's declared by the user. Specifically (N4950, [class.copy.ctor]/8):
> If the definition of a class X does not explicitly declare a move constructor, a non-explicit 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.
So even when you define the dtor to be exactly what the compiler would produce by default, you've still declared it, in which case it's a user-declared dtor, and the compiler no longer generates a move-ctor implicitly (nor move assignment).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论