首页 > 解决方案 > 已弃用的隐式声明的复制构造函数

问题描述

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

#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指出:

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

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

标签: c++c++11c++17typetraitsstatic-assert

解决方案


is_trivially_copy_constructible<T>还要求T可以简单地破坏。该特征检查的是假设变量定义是否:

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

不会调用任何重要的操作。Buttest不是简单可破坏的,并且这种破坏隐含在该构造中。

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


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


推荐阅读