c – 检查模板类的某些专门化是否是特定类的基类

@H_403_1@现代STL中有std :: is_base_of.它允许我们确定第二个参数是从第一个参数派生的,或者它们是否是相同的类,或者否则确定它们之间是否没有这样的关系.

是否可以确定一个类是从一些具体的模板类派生的,而不区分其专业化涉及的具体实际参数?

说,我们有

template< typename ...types >
struct B {};

template< typename ...types >
struct D : B< types... > {};

是否可以定义类型特征:

template< typename T > is_derived_from_B;

当T是D的任何特殊化并且从std :: false_type派生时,如果T不是从B的任何专业化导出的,那么它来自std :: true_type?

解决方法

如果您可以假设派生类型使用B< Args ...>的公共继承(所以可以上传),那么可以使用以下SFINAE:
namespace detail
{
    template <typename Derived>
    struct is_derived_from_B
    {
        using U = typename std::remove_cv<
                                  typename std::remove_reference<Derived>::type
                                >::type;

        template <typename... Args>
        static auto test(B<Args...>*)
            -> typename std::integral_constant<bool,!std::is_same<U,B<Args...>>::value>;

        static std::false_type test(void*);

        using type = decltype(test(std::declval<U*>()));
    };
}

template <typename Derived>
using is_derived_from_B = typename detail::is_derived_from_B<Derived>::type;

测试:

static_assert(is_derived_from_B<const D<int,char,float>>::value,"!");
static_assert(!is_derived_from_B<int>::value,"!");
static_assert(!is_derived_from_B<B<int,int>>::value,"!");
static_assert(!is_derived_from_B<std::vector<int>>::value,"!");

DEMO 1

可以将其概括为接受任何基类模板:

namespace detail
{
    template <template <typename...> class Base,typename Derived>
    struct is_derived_from_template
    {
        using U = typename std::remove_cv<
                                  typename std::remove_reference<Derived>::type
                                >::type;

        template <typename... Args>
        static auto test(Base<Args...>*)
            -> typename std::integral_constant<bool,Base<Args...>>::value>;

        static std::false_type test(void*);

        using type = decltype(test(std::declval<U*>()));
    };
}

template <template <typename...> class Base,typename Derived>
using is_derived_from_template
                = typename detail::is_derived_from_template<Base,Derived>::type;

测试:

static_assert(is_derived_from_template<B,const D<int,"!");
static_assert(!is_derived_from_template<B,int>::value,B<int,std::vector<int>>::value,"!");

DEMO 2

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...