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

Deprecated implicitely-declared copy constructor

我正在努力思考隐式声明的复制构造函数的一个奇怪特征。以下面的例子为例。一旦用户实现自定义析构函数,复制构造函数就不再微不足道了,但仍会生成。

#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("%d\n", t2.i);
    return 0;
}

网络版:https://godbolt.org/z/t-8_W3

我对普通构造函数的理解是它们是由编译器生成的。但是,cppreference 声明:

The generation of the implicitly-defined copy constructor is deprecated if T has a user-defined destructor or user-defined copy assignment operator.

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

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

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

不会调用任何重要的操作。但是 test 并非易破坏,破坏隐含在该构造中。

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


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