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

275 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 answers

0
Sam Estep 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
Mr.C64 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
KABoissonneault 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
Daniel Frey 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.