Template Method Specialization with enable_if

I am writing a template class that stores std::functionso I can call it later. Here is the simplified code:

template <typename T>
struct Test
{
    void call(T type)
    {
        function(type);
    }
    std::function<void(T)> function;
};

The problem is that this template does not compile for the type void, because

void call(void type)

becomes undefined.

Specialization for a type voiddoes not alleviate the problem because

template <>
void Test<void>::call(void)
{
    function();
}

still incompatible with ad call(T Type).

So, using the new features of C ++ 11, I tried std::enable_if:

typename std::enable_if_t<std::is_void_v<T>, void> call()
{
    function();
}

typename std::enable_if_t<!std::is_void_v<T>, void> call(T type)
{
    function(type);
}

but it does not compile with Visual Studio:

error C2039: 'type': is not a member of 'std :: enable_if'

How would you deal with this problem?

+6
source share
3

SFINAE () /struct.

, .

,

   template <typename U = T>
   std::enable_if_t<std::is_void<U>::value> call()
    { function(); }

   template <typename U = T>
   std::enable_if_t<!std::is_void<U>::value> call(T type)
    { function(type); } 

, , U T

   template <typename U = T>
   std::enable_if_t<   std::is_same<U, T>::value
                    && std::is_void<U>::value> call()
    { function(); }

   template <typename U = T>
   std::enable_if_t<std::is_same<U, T>::value
                    && !std::is_void<U>::value> call(T type)
    { function(type); } 

p.s.: std::enable_if_t - , typename .

p.s.2: ++ 11, std::enable_if_t, ++ 14 std::is_void_v, ++ 17

+2

:

template <>
struct Test<void>
{
    void call()
    {
        function();
    }
    std::function<void()> function;
};
+4

void, , Test - , :

template <typename ...T>
struct Test
{
    void call(T ...type)
    {
        function(type...);
    }
    std::function<void(T...)> function;
};

, . , :

Test<> t;
t.call();

, , , , , .

+2
source

All Articles