std::is_copy/move_constructible失败,即使复制/移动构造函数是默认的

std::is_copy/move_constructible fails even though copy/move constructors are defaulted

本文关键字:移动 复制 构造函数 默认 失败 copy is move constructible std      更新时间:2023-10-16

我有一个类Input,它有默认的移动/复制构造函数。

Input(const Input &) = default;
Input(Input &&) = default;

但是,以下断言失败了。

static_assert(std::is_copy_constructible<Input>(), "Input is not copy-constructible");
static_assert(std::is_move_constructible<Input>(), "Input is not move-constructible");

为什么?

下面是一个完整的例子:

#include <type_traits>
class A {
public:
    A(const A &) = default;
    static_assert(std::is_copy_constructible<A>(), "");
};
int main() {
    // your code goes here
    return 0;
}

您的问题是static_assert在类声明中。编译器不能确定当它到达static_assert时,该类是可复制的还是可移动的,因为该类还没有完全定义。

问题是测试在类本身中。为了评估static_assert,编译器需要完成类。这是不可能的,因为static_assert需要为此进行评估。这是一个鸡和蛋的问题。

这个代码片段(在Ideone上运行)似乎运行得很好:

#include <type_traits>
class Input {
public:
  Input(const Input &) = default;
  Input(Input &&) = default;
};
int main() {
  static_assert(std::is_copy_constructible<Input>(), "");
  static_assert(std::is_move_constructible<Input>(), "");
}

在您的示例中,您隐式地将构造函数声明为private(类类型中的默认可访问性)。

如果在您的真实代码中也是这样,那么这可能就是问题所在。