gpt4 book ai didi

c++ - 用户提供的显式默认函数定义为已删除的情况

转载 作者:太空宇宙 更新时间:2023-11-04 11:25:02 27 4
gpt4 key购买 nike

N3797::8.4.2/4 [dcl.fct.def.default] 中有以下引述:

A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed.

我试图发明一个反射(reflect)该规则的示例。因为,标准说:

If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted;

以下代码应抛出有关已删除函数调用的错误:

#include <iostream>

using namespace std;

struct A
{
A(){ }
A(const A&&){ cout << "A(const&&)" << endl; }
A(const A&) = default;
};

A a;

A b = a;

int main() {
}

但它工作正常。您能否提供一个反射(reflect)这一点的实际例子?

DEMO

最佳答案

下面的例子解释了它:

class A {
public:
A(int a) : m_a(a) {}
const int m_a;
};

由于 m_a 是一个 const 成员,编译器隐式删除了复制赋值运算符函数 A& operator=(const A&)。所以你不能做以下事情

int main() {
A var1(1);
A var2(3);
var2 = var1;
}

您应该得到一个编译时错误,例如copy assignment operator implicitly deleted。现在你会很想明确地默认它

class A {
public:
A(int a) : m_a(a) {}
A& operator=(const A& other) = default;

const int m_a;
};

您仍然会遇到编译时错误,并且可能会看到类似explicitly defaulted function was implicitly deleted 的消息。但是如果你绝对需要赋值运算符 say 来复制其他非常量成员,你可以如下显式定义它。

class A {
public:
A(int a) : m_a(a) {}
A& operator=(const A& other) {
m_b = other.m_b;
}

const int m_a;
int m_b = 0;
};

我认为这背后的原因很明显。在构造期间初始化后,我们不能重新分配 const 变量(和不可复制的成员)。尽管有人可能会争辩说应该允许一种默认行为,即只复制非常量(和可复制的)成员。但是对于不知道这种行为的人来说,可能会有一种错误的印象,即 const 成员(和不可复制的)也被重新分配,从而导致各种错误。

关于c++ - 用户提供的显式默认函数定义为已删除的情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26954437/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com