First, let me introduce you a partial solution:
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
{ };
In common cases, it works:
is_tbase_of<std::vector, std::is_integral<int>>::value; // false
is_tbase_of<std::vector, std::vector<int>>::value; // true
But, it does not work on a «meta-returned» template template, for example:
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...
I have tried a lot of things, trying to get the second type template arguments (to compare the quoted type specialization) but it seems I can't get them to work. Even specializing is_tbase_of
for quote
(which would be a less general but sufficient option) seems to send me to the black corners of template pattern-matching.
You can check if you can change U<Args...>
to T<Args...>
and then check if the result stays the same:
#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()
{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With