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

322 Views Asked by At

I have a class Input, which has default move/copy constructors.

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

The following assertions fail however.

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

Why is that?

Here is a full example:

#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;
}
4

There are 4 best solutions below

0
On BEST ANSWER

Your problem is that the static_assert is in the class declaration. The compiler can't know for sure when it reaches the static_assert whether the class is copy- or move-constructible, because the class hasn't been fully defined yet.

1
On

This code snippet (live on Ideone) seems to work just fine:

#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>(), "");
}
1
On

In your example, you implicitly declared your constructors as private (default accessibility in class types).

If that's the case in your real code too, that might be the problem.

0
On

The problem is that you have the test within the class itself. In order to evaluate the static_assert, the compiler needs to complete the class. This is not possible as the static_assert needs to be evaluated for that. It's a chicken-and-egg problem.