使用类型特征来确保类型不能从自身派生
Using type trait to ensure a type cannot be derived from itself
我想静态地检查 class 是否是从基数 class 派生的,而不是从它自身派生的。以下是我尝试实现的示例。不幸的是,代码编译通过了(从没想过我会这么说)。
我希望第二个静态断言能够启动并看到我试图从其自身派生出 class。如果你们能帮助我更好地理解我做错了什么,我将不胜感激。我尝试在网上搜索没有成功。
#include <type_traits>
struct Base {};
template <typename T>
struct Derived : T {
static_assert(std::is_base_of<Base, T>::value, "Type must derive from Base");
static_assert(!(std::is_base_of<Derived, T>::value),
"Type must not derive from Derived");
};
int main(int argc, char** argv) {
Derived<Base> d__base; // should be OK
Derived<Derived<Base>> d_d_base; // should be KO
return 0;
}
Type must not derive from Derived
Derived
本身不是一个类型,它是一个模板,在 std::is_base_of<Derived, T>::value
中被解析为它所在上下文中的当前专业化,它永远不会是 T
。如果你有 Derived<Derived<Base>>
那么 T
就是 Derived<Base>
而没有指定模板参数的 Derived
就是 Derived<Derived<Base>>
,所以,和 T
是不一样的。
您可以添加类型特征来检查 T
是否为 Derived<something>
:
template <template<class...> class F, class T>
struct is_from_template {
static std::false_type test(...);
template <class... U>
static std::true_type test(const F<U...>&);
static constexpr bool value = decltype(test(std::declval<T>()))::value;
};
现在,使用它会阻止类型 Derived<Derived<Base>>
:
struct Base {};
template <typename T>
struct Derived : T {
static_assert(std::is_base_of<Base, T>::value,
"Type must derive from Base");
static_assert(!is_from_template<Derived, T>::value,
"Type must not derive from Derived<>");
};
int main() {
Derived<Base> d_base; // OK
// Derived<Derived<Base>> d_d_base; // error
}
我想静态地检查 class 是否是从基数 class 派生的,而不是从它自身派生的。以下是我尝试实现的示例。不幸的是,代码编译通过了(从没想过我会这么说)。
我希望第二个静态断言能够启动并看到我试图从其自身派生出 class。如果你们能帮助我更好地理解我做错了什么,我将不胜感激。我尝试在网上搜索没有成功。
#include <type_traits>
struct Base {};
template <typename T>
struct Derived : T {
static_assert(std::is_base_of<Base, T>::value, "Type must derive from Base");
static_assert(!(std::is_base_of<Derived, T>::value),
"Type must not derive from Derived");
};
int main(int argc, char** argv) {
Derived<Base> d__base; // should be OK
Derived<Derived<Base>> d_d_base; // should be KO
return 0;
}
Type must not derive from Derived
Derived
本身不是一个类型,它是一个模板,在 std::is_base_of<Derived, T>::value
中被解析为它所在上下文中的当前专业化,它永远不会是 T
。如果你有 Derived<Derived<Base>>
那么 T
就是 Derived<Base>
而没有指定模板参数的 Derived
就是 Derived<Derived<Base>>
,所以,和 T
是不一样的。
您可以添加类型特征来检查 T
是否为 Derived<something>
:
template <template<class...> class F, class T>
struct is_from_template {
static std::false_type test(...);
template <class... U>
static std::true_type test(const F<U...>&);
static constexpr bool value = decltype(test(std::declval<T>()))::value;
};
现在,使用它会阻止类型 Derived<Derived<Base>>
:
struct Base {};
template <typename T>
struct Derived : T {
static_assert(std::is_base_of<Base, T>::value,
"Type must derive from Base");
static_assert(!is_from_template<Derived, T>::value,
"Type must not derive from Derived<>");
};
int main() {
Derived<Base> d_base; // OK
// Derived<Derived<Base>> d_d_base; // error
}