已弃用隐式声明的复制构造函数

Deprecated implicitely-declared copy constructor

本文关键字:复制 构造函数 声明      更新时间:2023-10-16

我试图围绕隐式声明的复制构造函数的一个奇怪特征来思考。举个例子。一旦用户实现了自定义析构函数,复制构造函数就不再是简单的,而是仍然会生成。

#include <type_traits>
#include <cstdio>
struct test {
test() = default;
~test() {
}
test(const test&) = default;
int i{42};
};
static_assert(std::is_copy_constructible_v<test>, "werks"); // OK
static_assert(std::is_trivially_copy_constructible_v<test>, "sad"); // FAILS
int main() {
test t;
test t2(t);
printf("%dn", t2.i);
return 0;
}

在线版 : https://godbolt.org/z/t-8_W3

我对琐碎构造函数的理解是它们是由编译器生成的。但是,cpp首选项指出:

隐式定义的复制构造函数的生成为 如果 T 具有用户定义的析构函数或用户定义的副本,则不推荐使用 赋值运算符。

因此,隐式声明的构造函数似乎还有一种状态,即"弃用"。它不是"微不足道的",也不是用户实现的,但仍然由您的编译器生成......这是对的吗?是否有人知道类型特征或解决方法来验证构造函数是否"已弃用"?

is_trivially_copy_constructible<T>还要求T是微不足道的可破坏的。这个特征检查的是假设变量定义是否:

T t(declval<T const&>());

不会调用任何非平凡的操作。但test不是微不足道的可破坏的,这种破坏隐含在这种结构中。

如果将~test() { }更改为~test() = default,断言将不再触发。


关于弃用隐式定义的构造函数的说明无关紧要,因为您有一个显式默认的复制构造函数。