C++ 检查类是否从模板的任何模板实例化继承
我编写了一个小实用程序,用于测试类型是否继承了特定模板类的某些模板实例化,可以是直接继承,也可以是通过继承继承该模板的类。这是通过使用接受所提供模板的任何模板实例化的模板函数进行SFINAE检查和默认情况下的回退重载来完成的C++ 检查类是否从模板的任何模板实例化继承,c++,templates,inheritance,c++11,sfinae,C++,Templates,Inheritance,C++11,Sfinae,我编写了一个小实用程序,用于测试类型是否继承了特定模板类的某些模板实例化,可以是直接继承,也可以是通过继承继承该模板的类。这是通过使用接受所提供模板的任何模板实例化的模板函数进行SFINAE检查和默认情况下的回退重载来完成的 #包括 #包括 模板 结构派生自 { 静态constexpr bool value=decltype(isDerivedFrom::test(U())::value; 私人: 模板 静态标准::真实型试验(T); 静态标准:假_型试验(…); }; 模板 结构基{}; 结构
#包括
#包括
模板
结构派生自
{
静态constexpr bool value=decltype(isDerivedFrom::test(U())::value;
私人:
模板
静态标准::真实型试验(T);
静态标准:假_型试验(…);
};
模板
结构基{};
结构Base_D1:Base{};
结构Base_D2:Base{};
结构Base_D1_D1:Base_D1{};
结构NotDerived{};
int main()
{
std::cout您可以使用:
模板
结构派生自
{
私人:
模板
静态decltype(static_cast(std::declval()),std::true_type{})
测试(常数T&);
静态标准:假_型试验(…);
公众:
静态constexpr bool value=decltype(isDerivedFrom::test(std::declval())::value;
};
由于私有继承不可见,在最后一种情况下,trait返回false
(对于struct-Derived:private-Base{};
).废弃的TR2中曾经有一个traitstd::base
和std::direct\U base
部分,它仍然随GCC一起提供。您可以使用它来检查是否有任何基是模板实例化。此代码不正确,因为ifU
继承自T
和T
其中X
!=<代码>Y
,它不会检测到继承。顺便说一句:您可以使用静态断言(isDerivedFrom::value,“意外值”)进行编译时检查
而不是用stream进行手动目视检查。@Jarod42当然,这就是为什么我首先编写代码,打印到控制台只是感觉测试更自然。@johanneschaub多重继承的情况没有发生在我身上,很好。你建议什么解决方案?你能解释一下什么是decltype(static_cast(std::declval())),std::true_type{})有什么作用?为什么需要静态强制转换?静态强制转换是尝试(公开)将U
转换为T
,并使用SFINAE删除无效的大小写。(您的代码不使用SFINAE,只使用更好的匹配).运算符T
可以愚弄这一点吗?@Yakk不,因为转换函数从未被调用以转换为基类类型。如果T
不是基类类型,则在尝试转换之前模板参数推导将失败。但是,我相信如果T
具有公共构造函数T(const U&)
。您可能希望将静态\U cast更改为static\U cast
,这将消除此漏洞。
template<template<class> class T, class U>
struct isDerivedFrom
{
private:
template<class V>
static decltype(static_cast<const T<V>&>(std::declval<U>()), std::true_type{})
test(const T<V>&);
static std::false_type test(...);
public:
static constexpr bool value = decltype(isDerivedFrom::test(std::declval<U>()))::value;
};