Why is this template always evaluated to false_type?

Viewed 50

I would like to enable_if a member function exists in a class T, so I try to write the code below.

    template< typename T, typename = void >
    struct has_member_func : std::false_type {};

    template< typename T >
    struct has_member_func< T, decltype(&T::some_func) > : std::true_type {};

However, it always evaluate to std::false_type, even if class T does have a function named some_func. Why?

1 Answers

When you use it like has_member_func<X>, the 2nd template parameter would use the default value void; but the partial specialization's 2nd template parameter's type is not void, then the specialization won't be selected; unless you specify the 2nd template argument explicitly to make them match like has_member_func<X, decltype(&X::some_func)> (which seems meaningless).

LIVE

In the partial specialization, the 2nd template parameter should yield the type void too, then the specialization could be selected. You can apply std::void_t (since C++17) like

template< typename T >
struct has_member_func< T, std::void_t<decltype(&T::some_func)> > : std::true_type {};

LIVE

PS: Before C++17 you can make your own void_t easily.

Related