Is_base_of的泛型类型

is_base_of of generic type

本文关键字:泛型类型 base Is of      更新时间:2023-10-16

我试图断言模板参数将从一些基类派生。但是基类是泛型的,在断言上下文中,任何专门化类型之间没有区别。我如何断言模板形参是从任何专门化类型的泛型派生的?

我试着把它写成

base_generic:

template<typename T> struct base_generic{};

derived_generic:

template<typename T> struct derived_generic : public base_generic<T>{};

类与断言:

template<typename Tsource, typename Tderived_generic> 
struct encoder {
static_assert(std::is_base_of<base_generic<typename>, Tderived_generic>::value);
};

这段代码可以编译,但是断言失败

您可以为此创建一个trait,例如:

namespace detail
{
    template <template <typename > class C>
    struct is_base_of_any_helper
    {
        template <typename T>
        std::true_type operator ()(const C<T>*) const;
        std::false_type operator() (...) const;
    };
}
template <template <typename > class C , typename T>
using is_base_of_any =
    decltype(detail::is_base_of_any_helper<C>{}(std::declval<const T*>()));

演示

请注意,在某些极端情况下会失败,例如:

  • 多碱基C<Tx>
  • C<T>私有继承。

选自@PiotrSkotnicki评论

template <template <typename...> class Base, typename Derived>
struct is_base_of_template
{
    using U = typename std::remove_cv<Derived>::type;
    template <typename... Args>
    static std::true_type test(Base<Args...>*);
    static std::false_type test(void*);
    using type = decltype(test(std::declval<U*>()));
};
template <template <typename...> class Base, typename Derived>
using is_base_of_template_t = typename is_base_of_template<Base, Derived>::type;

您可以使用static_assert。

见:http://en.cppreference.com/w/cpp/language/static_assert

例如,如果你有一个基类

template< typename T >
class Base<T> {};

和派生的

template< typename T >
class Derived : public Base<T> {};

和你的用例

template< typename Tsource, typename Tstorage > 
class Test
{
    std::static_assert( std::is_base_of< base<T>, TStorage >::value );
}

如果不将其作为模板参数添加,则不可能得到T。

但是用一个简单的技巧,你就能得到它。你必须添加一个类型定义到Derived:

template< typename T >
class Derived : public Base<T> 
{
public:
    typedef T value_type;
};

可以在静态断言中使用。

template< typename Tsource, typename Tstorage > 
class Test
{
    std::static_assert( std::is_base_of< base<TStorage::value_type>, TStorage >::value );
}

因为Tstorage是一个派生类,所以它有value_type字段。