Search code examples
c++sfinae

SFINAE not working with member function of template class


I have a template class where I would like to remove a member function if the type satisfies some condition, that, as far as I understand, should be a very basic usage of SFINAE, for example:

template<class T>
class A
{
public:
    template<typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
    T foo () {
        return 1.23;
    }
};

However, this is results in an error "no type named 'type'", like SFINAE was not going on. This however works if foo is a function not member of a class. What is wrong with this implementation?


Solution

  • You're missing a dependent name for the compiler to use for SFINAE. Try something like this instead:

    #include <type_traits>
    
    template<class T>
    class A
    {
    public:
        template<typename Tp = T>
        typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type
        foo () {
            return 1.23;
        }
    };
    
    int main() {
        A<double> a;
        a.foo();
    }
    

    If the type T is not floating point, the declaration would be malformed (no return type) and the function would not be considered for the overload set.

    See it on godbolt.