#include <type_traits>

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() {
    X1 x1; X2 x2; X3 x3; X4 x4; // all compile. They shouldn't
    // all compile. They shouldn't:
    Base<X1> bx1; Base<X2> bx2; Base<X3> bx3; Base<X4> bx4; 
	// Base<Y1> y1; // static assert fires. This is the expected behavior
}