Why doesn’t SFINAE (enable_if) work for member functions of a class template?

SFINAE only works for deduced template arguments, i.e. for function templates. In your case, both templates are unconditionally instantiated, and the instantiation fails.

The following variant works:

struct Foo
{
    template <typename T>
    typename std::enable_if<std::is_same<T, A>::value>::type bar(T) {}

    // ... (further similar overloads) ...
};

Now Foo()(x) causes at most one of the overloads to be instantiated, since argument substitution fails in all the other ones.

If you want to stick with your original structure, use explicit class template specialization:

template <typename> struct Foo;

template <> struct Foo<A> { void bar() {} };
template <> struct Foo<B> { void bar() {} };

Leave a Comment