检查类是否从模板的任何模板实例化继承 [英] checking if a class inherits from any template instantiation of a template

查看:173
本文介绍了检查类是否从模板的任何模板实例化继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个小实用程序,用于测试类型是否继承了特定模板类的一些模板实例化,直接或通过继承继承模板的类。这是通过使用模板函数接受任何模板实例化提供的模板的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 because decltype(T()) fails if T::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 (for struct Derived : private Base<int> {};).

这篇关于检查类是否从模板的任何模板实例化继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆