Question: I am trying to write a template class with multiple type parameters `T1` and `T2`. The class has a private member of type `std::promise<T2>`. 

```
template <class T, class T2>
class Test
{
public:
    void setValue(T2 value)
    {
        promise.set_value(value);
    }

    void setValue()
    {
        promise.set_value();
    }

private:
    std::promise<T2> promise;
};

```

This class compiles just fine when `T2` is anything but void (as long as you don't call `setValue` without parameters. When `T2` is void, I get a compiler error:

```
error C2182: 'value' : illegal use of type 'void'

```

When `T2` is anything but void, I would like to use the first `setValue` method, which has a single parameter of type `T2`. When `T2` is void, I would like to use the second `setValue` method, which takes no parameters. I've looked at a lot of examples, but I am relatively new to template programming, and I can't seem to make it work.

Is it possible to accomplish this with std::enable\_if somehow? Or with template specialization?

Answer: 
helper template class specialisation:

```
#include <future>

template<typename T>
class TestHelper
{
public:
    void setValue(T const& v)
    { promise.set_value(v); }

private:
    std::promise<T> promise;
};

template<>
class TestHelper<void>
{
public:
    void setValue()
    { promise.set_value(); }

private:
    std::promise<void> promise;
};

template <class T, class T2>
class Test : public TestHelper<T2>
{
};

int main()
{
    Test<void, int> t;
    // t.setValue(); // compilation error: no matching function for call to 'std::promise<int>::set_value()'
    t.setValue(0);

    Test<void, void> t1;
    t1.setValue();
    // t1.setValue(0); // compilation error: no matching function for call to 'std::promise<void>::set_value(int)'
}

```
You can solve this problem with a conditional dependency on a base class:

```
#include <future>
#include <type_traits>
#include <iostream>

template<class T2>
struct Base {
protected:
    std::promise<T2> promise;
};

template<class T2>
struct BaseWithVariable : public Base<T2> {
    void setValue(T2 value)
    {
        this->promise.set_value(value);
    }
};

template<typename T2>
struct BaseWithoutVariable : public Base<T2> {
    void setValue()
    {
        this->promise.set_value();
    }
};

template<typename T, typename T2>
class Test
: public std::conditional<std::is_same_v<T2, void>, BaseWithoutVariable<T2>, BaseWithVariable<T2>>::type
{
};

int main()
{
    Test<int, int> a;
    a.setValue(5);
    Test<int, void> b;
    b.setValue();
}

```

Now you realize that you can achieve the same with specialization on the level of the intermediate class:

```
template<class T2>
struct BaseSetter : public Base<T2> {
    void setValue(T2 value)
    {
        this->promise.set_value(value);
    }
};

template<>
struct BaseSetter<void> : public Base<void> {
    void setValue()
    {
        this->promise.set_value();
    }
};

template<typename T, typename T2>
class Test : public BaseSetter<T2>
{
};

```

And it would also not hurt, in this particular case, to omit the use of `Base` and just have both variants of `BaseSetter` use their own member variable `std::promise<T2>`, or `std::promise<void>`, respectively.

However all of these crash in runtime with GCC 7.2.0. I don't know why.