为啥可以删除任何函数,但只能删除默认的特殊成员函数? [复制]

Posted

技术标签:

【中文标题】为啥可以删除任何函数,但只能删除默认的特殊成员函数? [复制]【英文标题】:Why can you delete any function, but only default special member functions? [duplicate]为什么可以删除任何函数,但只能删除默认的特殊成员函数? [复制] 【发布时间】:2014-12-01 17:23:02 【问题描述】:

以前:

Can non-special C++ member functions be deleted (or defaulted)?

Can any function be a deleted-function?

我们知道只有特殊的成员函数可以被默认,但是任何函数都可以被删除。

N3337:

[dcl.fct.def.default]

表单的函数定义:

            attribute-specifier-seqoptdecl-specifier-seqopt声明符 = 默认;

被称为显式默认定义。一个函数是 明确默认应

——是一个特殊的成员函数,

——具有相同的声明函数类型(除了可能不同 ref-qualifiers 并且除了在复制构造函数或复制赋值运算符的情况下,参数类型可以是“引用 非常量 T”,其中 T 是成员函数类的名称) 好像它已被隐式声明,并且

——没有默认参数。

[dcl.fct.def.delete]

表单的函数定义:

            attribute-specifier-seqoptdecl-specifier-seqopt声明符 = 删除;

被称为已删除的定义。具有已删除定义的函数 也称为删除函数

我的问题是,为什么会这样?如果标准可以允许删除任何功能,我认为允许默认任何功能没有什么害处。 n2210 的措辞似乎暗示允许默认的免费功能。例如,

在Changes to the Standard 下,它说:

[...]

添加一个新的第 7 段。

“=default;”的函数定义,称为显式默认定义,具有隐式默认的实现 定义(12.1、12.4、12.8)。 [ 注意:成员函数 类定义之外的显式默认定义必须 也可以在类定义中声明。 — 尾注 ] 与 隐式默认定义,显式默认定义 可能是非内联的。 [...]

3 年后,N3025 已经建立了类似于最终草案的语言,并将默认函数明确限制为特殊成员函数。在这 3 年的差距中是否有论文或解释这一点的一些理由?

【问题讨论】:

另外,-1 用于链接问题而不阅读它们。您的第一个链接完全涵盖了只有具有默认值的函数才能被默认的事实。从那个问题:“我可以理解 = default 可能不允许在特殊成员之外;因为它基本上是说使用编译器生成的默认值。在编译器能够生成它之前需要明确定义默认值.. . 只有特殊成员才有这些预定义的默认值。” 【参考方案1】:

因为只有特殊的成员函数具有明确定义的“默认”定义,如果您不声明该函数或任何其他会禁止它的函数,则会隐式生成。

如果我要写作

int f() = default;

你希望这个函数做什么?

【讨论】:

如果我必须回答这个问题,我会说它会抛出 std::bad_function_call :o) +1 根据我在 SO 上的经验,我想说int f() = default; 应该定义一个输出"Hello, world!" 并返回42 的函数。我会让你成为我提议的共同作者,将这个特性添加到 C++17 中;)【参考方案2】:

逻辑根本没有改变,只是措辞。看原文

“=default;”的函数定义,称为显式默认定义,完全具有隐式默认定义的实现

只有特殊的成员函数具有“隐式默认定义”。试图显式默认任何其他函数是错误定义的,因为它是根据不存在的东西定义的(隐式默认定义)。

【讨论】:

以上是关于为啥可以删除任何函数,但只能删除默认的特殊成员函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Don Box - Essential COM:当删除运算符是成员函数时,为啥要将创建运算符定义为非成员函数?

成员函数

特殊作用的私有成员函数

C++类的特殊成员-默认/拷贝/移动构造函数

为啥在特殊成员函数中将 r 值绑定到 const 左值引用是非法的?

为啥工会成员数据没有默认初始化?