Artur Pyszczuk
Artur Pyszczuk

Reputation: 1940

SFINAE: no type named ‘type’ when member function is not a template

Consider following example:

template <typename T>
struct Boo {

    template <typename K = T>
    static typename enable_if<is_same<K, X1>::value, void>::type foo (int, int) {}

    template <typename K = T>
    static typename enable_if<is_same<K, X2>::value, void>::type foo (int) {}
};

template <typename T>
struct Goo {
    static typename enable_if<is_same<T, X1>::value, void>::type foo (int, int) {}

    static typename enable_if<is_same<T, X2>::value, void>::type foo (int) {}
};

And usage:

Boo<X1>::foo (1, 1);
Boo<X1>::foo (1);       // (1)
Boo<X2>::foo (5);
Boo<X2>::foo (5, 5);    // (2)

Goo<X1>::foo (1, 2);    // (3)
Goo<X2>::foo (2);       // (4)

(1) and (2) don't compile and this is what I wanted, but could someone explain me why (3) and (4) can not be compiled? So, why Goo::foo (int, int) and Goo::foo (int) if they are not templates, can not be used the same way as Boo::foo (int, int), Boo::foo (int).

Upvotes: 2

Views: 1315

Answers (1)

SergeyA
SergeyA

Reputation: 62583

The answer is very simple - SFINAE works on functions themsleves. It does not work on their containment classes. Since in the second case the functions themselves are not templates, their instances are created when the class is instantiated - and all the types must be correct. Only template functions can be simply discarded from overload resolution.

Small illustration. Even this code will fail to compile:

Goo<X1> a;

There is no function called here at all, yet the code will fail to compile - because compiler will not be able to create the functions required for the class instance.

Upvotes: 3

Related Questions