如何比较模板模板和模板实例?

web*_*nra 11 c++ templates metaprogramming c++11 c++14

首先,让我向您介绍一个部分解决方案:

template <template <class...> class,
        typename ...>
struct is_tbase_of:
  std::false_type
{ };

template <template <class...> class Type,
          typename ...Args>
struct is_tbase_of<Type, Type<Args...>>:
  std::true_type
{ };
Run Code Online (Sandbox Code Playgroud)

在一般情况下,它的工作原理:

is_tbase_of<std::vector, std::is_integral<int>>::value; // false
is_tbase_of<std::vector, std::vector<int>>::value;      // true
Run Code Online (Sandbox Code Playgroud)

但是,它不适用于"元返回"模板模板,例如:

template <template <class ...> class T>
struct quote
{
  template <typename ...U>
  using type = T<U...>;
};

using QVec =  quote<std::vector>;
is_tbase_of<QVec::template type, std::vector<int>>::value; // false...
Run Code Online (Sandbox Code Playgroud)

我尝试了很多东西,尝试获取第二个类型的模板参数(比较引用的类型特化)但似乎我无法让它们工作.即使专注is_tbase_ofquote(这将是一个不太通用但足够的选项)似乎将我发送到模板模式匹配的黑角.

Ale*_*lex 4

您可以检查是否可以更改U<Args...>T<Args...>然后检查结果是否保持不变:

#include <type_traits>
#include <vector>

struct is_tbase_of_impl
{
    struct err {};

    template <template <class...> class T, class U>
    static err test(U*);

    template <template <class...> class T, template <class...> class U, class... Args>
    static T<Args...> test(U<Args...>*);
};

template <template <class...> class T, class U>
using is_tbase_of
    = typename std::is_same< decltype(is_tbase_of_impl::test<T>((U*)0)), U >::type;

template <template <class...> class T>
struct quote
{
    template <class... U>
    using type = T<U...>;
};

using QVec = quote<std::vector>;

template <class...> struct S {};

static_assert( !is_tbase_of< std::vector, std::is_integral<int>  >::value, "" );
static_assert(  is_tbase_of< std::vector, std::vector<int>       >::value, "" );
static_assert(  is_tbase_of< QVec::type,  std::vector<int>       >::value, "" );
static_assert( !is_tbase_of< std::vector, S<int, int, int>       >::value, "" );

int main()
{
}
Run Code Online (Sandbox Code Playgroud)