Computing the template template

Let's say I have the following two test classes:

struct TestYes {
    using type = void;
    template <typename... T>
    using test = void;
};

struct TestNo { };

      

and I want to determine if they have this template member test

.

For a member type

,

template <typename, typename = void>
struct has_type_impl {
    using type = std::false_type;
};
template <typename T>
struct has_type_impl<T, typename T::type> {
    using type = std::true_type;
};
template <typename T>
using has_type = typename has_type_impl<T>::type;

      

works great:

static_assert( has_type<TestYes>::value, ""); // OK
static_assert(!has_type<TestNo>::value, "");  // OK

      

but the equivalent for a template member is test

:

template <typename, template <typename...> class = std::tuple>
struct has_test_impl {
    using type = std::false_type;
};
template <typename T>
struct has_test_impl<T, T::template test> {
    using type = std::true_type;
};
template <typename T>
using has_test = typename has_test_impl<T>::type;

      

does not work

static_assert( has_test<TestYes>::value, "");

      

I know I can use SFINAE, for example:

template <typename T>
struct has_test_impl {
private:
    using yes = std::true_type;
    using no = std::false_type;

    template <typename U, typename... Args>
    static auto foo(int) -> decltype(std::declval<typename U::template test<Args...>>(), yes());

    template <typename> static no foo(...);

public:
    using type = decltype(foo<T>(0));
};

template <typename T>
using has_test = typename has_test_impl<T>::type;

      

but I'm wondering why the compiler subtracts the partial specialization correctly has_type_impl

while it stays in the first definition has_test_impl

.

Thanks for your enlightenment!

+3


source to share


1 answer


template<template<class...> class...>
using void_templ = void;

template <typename, typename = void>
struct has_test_impl {
    using type = std::false_type;
};
template <typename T>
struct has_test_impl<T, void_templ<T::template test>> {
    using type = std::true_type;
};

      



+2


source







All Articles