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
的构造函数中,它会正常工作
如果 T
从 Base
派生,is_default_constructible<T>
在 class 级别总是错误的原因是什么?
当Base<X1>
实例化在X1
的继承列表中时,X1
是一个不完整的类型。这意味着当检查 class-scope static_assert
时 X1
不是 default-constructible。
Base
的构造函数仅在使用时实例化,此时 X1
现在是一个完整的类型并且是 default-constructible。这就是为什么 static_assert
在构造函数内部触发,而不是在 class-scope.
触发的原因
根据 ,当 T
为 X
时,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.
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
如果 T
从 Base
派生,is_default_constructible<T>
在 class 级别总是错误的原因是什么?
当Base<X1>
实例化在X1
的继承列表中时,X1
是一个不完整的类型。这意味着当检查 class-scope static_assert
时 X1
不是 default-constructible。
Base
的构造函数仅在使用时实例化,此时 X1
现在是一个完整的类型并且是 default-constructible。这就是为什么 static_assert
在构造函数内部触发,而不是在 class-scope.
根据 T
为 X
时,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.