问题
I need a meta-function that for given complete class type returns its template (e.g. f<foo<bar>>::type
or f<foo<baz>>::type
results in foo
).
Or it may return true
on f<foo<bar>, foo<baz>>::value
and false
on f<foo<bar>, not_foo<baz>>::value
P.S: this was meant to be used with many chrono::duration like classes (but for weight units, mass units and so on). I needed different units not to convert one to another.
回答1:
f<foo<bar>>::type or f<foo<baz>>::type results in foo
Not exactly (see is-an-alias-template-considered-equal-to-the-same-template), you can do something like:
template <typename T> struct template_class;
template <template <typename> class C, typename T>
struct template_class<C<T>>
{
template <typename U>
using type = C<U>;
};
Or it may return true on
f<foo<bar>, foo<baz>>::value
and false onf<foo<bar>, not_foo<baz>>::value
It is easier, even if limited, specialization mostly as is_same
:
template <typename, typename> struct has_same_template_class : std::false_type{};
template <template<typename> class C, typename T1, typename T2>
struct has_same_template_class<C<T1>, C<T2>> : std::true_type{};
回答2:
Probably, you want something like this:
#include <type_traits>
template<class> struct foo;
template<class> struct not_foo;
struct bar;
struct baz;
template<class, class>
struct trait : std::false_type {};
template<template<class> class T, class S1, class S2>
struct trait<T<S1>, T<S2>> : std::true_type {};
static_assert( trait<foo<bar>, foo<baz> >::value);
static_assert( trait<not_foo<bar>, not_foo<baz>>::value);
static_assert(!trait<foo<bar>, not_foo<baz>>::value);
static_assert(!trait<foo<bar>, not_foo<bar>>::value);
Demo
来源:https://stackoverflow.com/questions/61278669/is-there-a-way-to-get-type-of-template-class-from-its-complete-type