Metafunction to detect template class inheritance via CRTP

I have an interface that looks like this:

template<typename Concrete, typename T>
class Interface{
    ...
}

and its specific implementation:

template<typename T>
class Concrete : public Interface<Concrete<T>, T>
{
    ...
    using type = typename T;
}

I would like to have a metafunction that could check if a certain type comes from Interface.

As an example, suppose an interface has only one template argument (and therefore, it will not generate template classes for children):

template<typename Concrete>
class A
{
    ...
}

class B : public A<B>
{
    ...
}

in this case, I could use:

template<typename T>
struct is_A
{
    static bool const value = std::is_base<A<T>, T>::value;
}

My question is the best approach for creating a similar metafunction for the case when there is an additional template argument. It should look like this:

template<typename T>    
struct is_Interface{}

To be clear, I could produce

 template<template <class> class T>    
 struct is_Interface
 {
  using dummy_type = void;
  static bool const value = std::is_base<Interface<T<dummy_type>, dummy_type>, T<dummy_type>>::value;
 }

but I would like for me to pass a specific type, not a template class.

+4
1

:

template <template <class> class Concrete, class T>
std::true_type is_Interface_impl(Interface<Concrete<T>, T> *);

std::false_type is_Interface_impl(...);

template<typename T>
struct is_Interface : decltype(is_Interface_impl(std::declval<T*>())) { };

, is_Interface_impl . , SFINAE, vararg.

Coliru!

+4

Source: https://habr.com/ru/post/1676898/


All Articles