如何在编译时确定类型是否从模板 class 派生?
How to determine if a type is derived from a template class at compile time?
说我有一些模板 类:
template<class T>
class Foo{}
template<class T>
class Bar{}
现在,我想确保(在编译时)Bar
中使用的类型派生自 Foo
。我已经找到 this 答案,显示了如何在运行时执行此操作,但我想在编译时检查,也许使用 static_assert
或其他东西。
有办法吗?
Now, I want to make sure (at compiletime) that the type used in Bar is derived from Foo.
你可以这样做:
#include<type_traits>
#include<utility>
template<class T>
class Foo{};
template<typename T>
std::true_type test(const Foo<T> &);
std::false_type test(...);
template<class T>
class Bar {
static_assert(decltype(test(std::declval<T>()))::value, "!");
};
struct S: Foo<int> {};
int main() {
Bar<S> ok1;
Bar<Foo<int>> ok2;
// Bar<int> ko;
}
在 wandbox 上查看。
基本思想是,如果 T
派生自 Foo
的特化,则可以将类型 T
的临时值绑定到 const Foo<U> &
,而不管 U
是什么。因此,您可以声明(无需定义)几个函数,例如示例中的函数来测试它,然后在 static_assert
或任何其他常量上下文中使用声明的 return 类型。
编辑
正如@Quentin 在评论中所建议的,可能值得用指针替换引用以防止转换构造函数和运算符的误报。
说我有一些模板 类:
template<class T>
class Foo{}
template<class T>
class Bar{}
现在,我想确保(在编译时)Bar
中使用的类型派生自 Foo
。我已经找到 this 答案,显示了如何在运行时执行此操作,但我想在编译时检查,也许使用 static_assert
或其他东西。
有办法吗?
Now, I want to make sure (at compiletime) that the type used in Bar is derived from Foo.
你可以这样做:
#include<type_traits>
#include<utility>
template<class T>
class Foo{};
template<typename T>
std::true_type test(const Foo<T> &);
std::false_type test(...);
template<class T>
class Bar {
static_assert(decltype(test(std::declval<T>()))::value, "!");
};
struct S: Foo<int> {};
int main() {
Bar<S> ok1;
Bar<Foo<int>> ok2;
// Bar<int> ko;
}
在 wandbox 上查看。
基本思想是,如果 T
派生自 Foo
的特化,则可以将类型 T
的临时值绑定到 const Foo<U> &
,而不管 U
是什么。因此,您可以声明(无需定义)几个函数,例如示例中的函数来测试它,然后在 static_assert
或任何其他常量上下文中使用声明的 return 类型。
编辑
正如@Quentin 在评论中所建议的,可能值得用指针替换引用以防止转换构造函数和运算符的误报。