CRTP std::is_default_constructible 未按预期工作

CRTP std::is_default_constructible not working as expected

template <class T>
class Base {
     static_assert(!std::is_default_constructible<T>::value,
                   "T must not be default constructible");
};

struct X1 : Base<X1> {};
struct X2 : Base<X2> {
   X2() = default;
};
struct X3 : Base<X3> {
   X3() {};
};
struct X4 : Base<X4> {
   X4() : Base{} {};
};

struct Y1 {};

int main() {
    // all compile. They shouldn't
    X1 x1; X2 x2; X3 x3; X4 x4; 
    // all compile. They shouldn't:
    Base<X1> bx1; Base<X2> bx2; Base<X3> bx3; Base<X4> bx4;  

    Base<Y1> by1; // static assert fires. This is the expected behavior
}

class 级别的 static_assert 不会触发 X class 中的任何一个。但是开始 Y(不派生 Base

如果将 static_assert 移动到 Base

的构造函数中,它会正常工作

如果 TBase 派生,is_default_constructible<T> 在 class 级别总是错误的原因是什么?

Ideone

Base<X1>实例化在X1的继承列表中时,X1是一个不完整的类型。这意味着当检查 class-scope static_assertX1 不是 default-constructible。

Base 的构造函数仅在使用时实例化,此时 X1 现在是一个完整的类型并且是 default-constructible。这就是为什么 static_assert 在构造函数内部触发,而不是在 class-scope.

触发的原因

根据 ,当 TX 时,T 在 class 级别不完整。

我想在 Undefined Behavior 中添加此结果,因为 T 必须是 is_default_constructible 的完整类型:

cppreference docs for is_default_constructible:

T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound. Otherwise, the behavior is undefined.