Ivan Smirnov
Ivan Smirnov

Reputation: 4435

SFINAE-based template method specialization

I've got a template class with some method, say, foo. I want to specify a default behavior for this method for all POD types and introduce separate specializations for other types. (The real problem is more complicated but this is an MWE.) I tried to do it with SFINAE in a usual way.

template<typename T>
class C {
public:
    void foo(T t);
};

template<typename T>
typename std::enable_if<
        std::is_pod<T>::value,
        void>::type
C<T>::foo(T t) {
    // do something
}

Even with this code (i.e. not making any instances of C) I've got an error:

prototype for ‘typename std::enable_if<std::is_pod<_Tp>::value, void>::type C<T>::foo(T)’ does not match any in class ‘C<T>’

This seems strange for me, because either both method types are void or the second one is eliminated by SFINAE.

What is more weird, if I replace a condition within enable_if with false, I got an error which shows that SFINAE doesn't work at all:

error: ‘type’ in ‘struct std::enable_if<false, void>’ does not name a type

Where am I wrong?

Upvotes: 0

Views: 138

Answers (1)

Edward Strange
Edward Strange

Reputation: 40859

For SFINAE to apply the identifier must be a template and substitution has to be involved.

First case fails because foo is not a template.

Second case fails for same reason and because no substitution is involved.

Upvotes: 1

Related Questions