quant
quant

Reputation: 23052

How do I declare a method only if a template parameter of the class passes some test?

Having read the cppreference docs on std::enable_if, I know I can do something like this:

// foo2 overload is enabled via a parameter
template<class T>
T foo2(T t, typename std::enable_if<std::is_integral<T>::value >::type* = 0) 
{
    return t;
}

But what if the template parameter being tested is from the class' template, not that of the method?

In the following example, I'm trying to overload a base class method if some template argument of the derived class is a floating point type:

class Base
{
public:
    template <typename X>
    void fun() {}
};

template <typename T>
class Derived : public Base
{
public:
    template <typename X, typename std::enable_if<std::is_floating_point<T>::value, void>::type* = nullptr>
    void fun() {}
};

int main()
{
    Derived<double> d1;
    Derived<int> d2;
    return 0;
}

How do I make this work? Currently, I'm getting:

error: no type named ‘type’ in ‘struct std::enable_if’

Upvotes: 0

Views: 104

Answers (1)

T.C.
T.C.

Reputation: 137320

You'd probably want to use partial specializations for this. Using enable_if on the template member function itself (which can be done, just add another template parameter with a default value of T and use enable_if on that parameter) will still hide the base class function.

class Base
{
public:
    template <typename X>
    void fun() { std::cout << "Base fun()" << std::endl; }
};

template <typename T, bool is_float = std::is_floating_point<T>::value>
class Derived : public Base
{
public:
    template <typename X>
    void fun() { std::cout << "Derived fun()" << std::endl;}
};

template <typename T>
class Derived<T, false> : public Base
{

};

Demo.

Upvotes: 1

Related Questions