Blood-HaZaRd
Blood-HaZaRd

Reputation: 2124

Can I get rid of template specialisation with std::enable_if?

I read about std::enable_if for:

function overloading based on arbitrary properties of type

So I was trying to overload class ctors via enable_if (like below) but i get error saying that enable_if cannot be used to disable declaration and this in both lines when I used std::enable_if :

#include <iostream>
#include <type_traits>
#include <typeinfo>


template <typename T>
class cls
{
public:

    cls (T a, typename std::enable_if< std::is_same<T, int>::value >::type  * Dummy = 0)
    {
        std::cout << "Ctor for int\n";
    }

    cls (T a, typename std::enable_if< std::is_same<T, char>::value >::type  * Dummy = 0)
    {
        std::cout << "Ctor for char\n";
    }
};

int main()
{

    cls a(10);
    cls b('x');

    return 0;
}

So is it possible to overload ctors using enbale_if.

Upvotes: 4

Views: 322

Answers (2)

songyuanyao
songyuanyao

Reputation: 172924

The problem is, e.g. when you instantiate a cls<int>, you'll always get a failed requirement from the 2nd constructor overloaing, i.e. std::enable_if< std::is_same<T, char>::value >::type with T is int. And it's same for cls<char>.

You can make the constructors templates to make SFINAE taking effect; which will get rid of template specializations from the overload set and won't cause compile error. e.g.

template <typename X = T>
cls (X a, typename std::enable_if< std::is_same<X, int>::value >::type  * Dummy = 0)
{
    std::cout << "Ctor for int\n";
}

template <typename X = T>
cls (X a, typename std::enable_if< std::is_same<X, char>::value >::type  * Dummy = 0)
{
    std::cout << "Ctor for char\n";
}

LIVE

Upvotes: 3

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136256

You don't seem to need enable_if here, just a regular constructor:

cls(T a) { std::cout << "Ctor for T\n"; }

To disable a template class specialization do not provide its definition:

template<> class cls<void>; // disabled specialization.

Upvotes: 2

Related Questions