检查类是否从模板的任何模板实例化继承 [英] checking if a class inherits from any template instantiation of a template
问题描述
我写了一个小实用程序,用于测试类型是否继承了特定模板类的一些模板实例化,直接或通过继承继承模板的类。这是通过使用模板函数接受任何模板实例化提供的模板的SFINAE检查以及默认情况下的回退重载来完成的。
#include< iostream>
#include< type_traits>
template< template< class>类T,类U>
struct isDerivedFrom
{
static constexpr bool value = decltype(isDerivedFrom :: test(U())):: value;
private:
template< class V>
static std :: true_type test(T< V>);
static std :: false_type test(...);
};
template< class T>
struct Base {};
struct Base_D1:Base< int> {};
struct Base_D2:Base< Base_D2> {};
struct Base_D1_D1:Base_D1 {};
struct NotDerived {};
int main()
{
std :: cout< std :: boolalpha
<< 是Base_D1派生自或Base的模板实例化:
<< isDerivedFrom< Base,Base_D1> :: value<< \\\
<< 是Base_D2派生自或Base的模板实例化:
<< isDerivedFrom< Base,Base_D2> :: value<< \\\
<< 是Base_D1_D1派生自或Base的模板实例化:
< isDerivedFrom< Base,Base_D1_D1> :: value<< \\\
<< 是从Base派生的Base< double>或Base的模板实例化:
< isDerivedFrom< Base,Base< double>> :: value<< \\\
<< is NotDerived derived from or a template instantiation of Base:
<< isDerivedFrom< Base,NotDerived> :: value<< \\\
;
return 0;
}
输出:
是Base_D1派生自或Base的模板实例化:
是Base_D2派生自或Base的模板实例化:
Base_D1_D1派生自或base的模板实例化:base $ true
是Base< double>派生自或基于模板实例化Base:true
是NotDerived派生自或模板实例化Base:false
我的问题是,如果要测试的类型(
的模板参数T isDerivedFrom
)具有或继承一个非公共构造函数或继承模板,公共继承,它会导致编译错误,因为decltype(T())
失败,如果T :: T()
不公开:struct Base {protected:Base(){}};
struct Derived:private Base< int> {};
有没有办法使这项工作适用于所有情况?
解决方案您可以使用: https://ideone.com/wR2dLX
模板< template< class>类T,类U>
struct isDerivedFrom
{
private:
template< class V>
static decltype(static_cast< const T>&>(std :: declval< U>()),std :: true_type {})test(const T&
static std :: false_type test(...);
public:
static constexpr bool value = decltype(isDerivedFrom :: test(std :: declval< U>()))
};
由于私有继承不可见,trait返回
false
在最后一种情况下(struct Derived:private Base< int> {};
)。I have written a small utility for testing whether or not a type has inherited some template instantiation of a specific template class, either directly or trough inheriting a class that inherits the template. This is accomplished with a SFINAE check using a template function accepting any template instantiation of the provided template and a fallback overload for the default case.
#include <iostream> #include <type_traits> template<template<class> class T, class U> struct isDerivedFrom { static constexpr bool value = decltype(isDerivedFrom::test(U()))::value; private: template<class V> static std::true_type test(T<V>); static std::false_type test(...); }; template<class T> struct Base {}; struct Base_D1 : Base<int> {}; struct Base_D2 : Base<Base_D2> {}; struct Base_D1_D1 : Base_D1 {}; struct NotDerived {}; int main() { std::cout << std::boolalpha << "is Base_D1 derived from or a template instantiation of Base: " << isDerivedFrom<Base, Base_D1>::value << "\n" << "is Base_D2 derived from or a template instantiation of Base: " << isDerivedFrom<Base, Base_D2>::value << "\n" << "is Base_D1_D1 derived from or a template instantiation of Base: " << isDerivedFrom<Base, Base_D1_D1>::value << "\n" << "is Base<double> derived from or a template instantiation of Base: " << isDerivedFrom<Base, Base<double>>::value << "\n" << "is NotDerived derived from or a template instantiation of Base: " << isDerivedFrom<Base, NotDerived>::value << "\n"; return 0; }
Output:
is Base_D1 derived from or a template instantiation of Base: true is Base_D2 derived from or a template instantiation of Base: true is Base_D1_D1 derived from or a template instantiation of Base: true is Base<double> derived from or a template instantiation of Base: true is NotDerived derived from or a template instantiation of Base: false
My problem is that if the type to be tested (template argument T of
isDerivedFrom
) has or inherits a non-public constructor or inherits the template trough non-public inheritance, it causes a compile error becausedecltype(T())
fails ifT::T()
is not public:struct Base {protected: Base(){}}; struct Derived : private Base<int> {};
Is there any way to make this work for all cases? Are there any unmentioned issues with the code?
解决方案You may use: https://ideone.com/wR2dLX
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; };
As private inheritance is not visible, the trait returns
false
in the last case (forstruct Derived : private Base<int> {};
).这篇关于检查类是否从模板的任何模板实例化继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!