问题描述
似乎在 C++20 中引入了一种称为“预期析构函数”的东西。 在C++17 [class.dtor]:
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier(opt) attribute-specifier-seq(opt)
在 C++20 中,这已更改为 this:
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier(opt) attribute-specifier-seq(opt)
那么这个“预期的析构函数”是什么?好吧,标准似乎没有澄清,至少对我来说:
引入“预期析构函数”这个新概念的原因是什么?它甚至是什么意思?它如何更改代码?它允许做什么?
我认为这可能是为了用于模板元编程,或者可能与 SFINAE 有某种关系,但这些只是猜测。
解决方法
它的意思就是它所说的意思。它是一个“析构函数”,由英文单词“prospective”修饰,意思是“潜在的、可能的或预期的”。所以它是一个潜在的析构函数。
概念的目的是允许...概念。
析构函数是具有特殊属性和行为的特殊成员函数。但最重要的是,您只能拥有一个,并且您必须在使用类时立即知道您拥有的是哪个(甚至与默认构造函数不同)。
然而,如果你想根据类的模板参数是否满足某个概念来有不同的析构函数实现,那就意味着你必须有多个析构函数。它们将根据 requires
子句进行区分。
考虑std::optional<T>
。如果 optional<T>
有一个平凡的析构函数,那么 T
的析构函数必须是平凡的。但是如果 optional
被占用,非平凡形式需要显式调用非平凡析构函数。所以这是两个函数体:= default
和 { /*actual code*/ }
。
从历史上看,这是通过使用专门确定 T
是否具有简单析构函数的基类或成员类型来完成的。但是适当的 requires
子句可以使其更容易实现。
根据您引用的标准的一部分,稍后确定哪个析构函数声明继续存在。进行重载解析需要对所有“预期析构函数”进行模板替换。这会导致 requires
子句无法消失的任何此类析构函数。如果此过程解析为单个析构函数,那么这就是实际的析构函数。如果它解析为多个析构函数,则代码格式错误。