Will compiler still generate default move constructor if I declare a deconstructor but exactly as same as the default deconstructor?

huangapple go评论56阅读模式
英文:

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&amp; lv) {cout &lt;&lt; &quot;a copy ctor.&quot; &lt;&lt; endl;}
    A(A&amp;&amp; rv) {cout &lt;&lt; &quot;a move ctor.&quot; &lt;&lt; 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).

huangapple
  • 本文由 发表于 2023年6月26日 08:55:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76552965.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定