Search code examples
templatesc++17

How to use void for std::conditional_t in C++17


I try to define the std::function template arguments of a class member based on a std::conditional_t type:

template <class T, size_t N = 1>
class MyClass {
    static_assert( (N > 0), "0 or less feature element isn't allowed");
public:
    typedef std::conditional_t<(N == 1), void, uint32_t> index_t;

private:
    std::function<T(index_t)> fRead;

public:
    template <typename U = T>
    std::enable_if_t<(N==1), U> getData()
    { return fRead(); }
    template <typename U = T>
    std::enable_if_t<(N>1), U> getData(uint32_t index)
    {
        if (index >= N) {
            throw std::out_of_range ("Index is out of range!");
        }
        return fRead(index);
    }
}

The fRead type should be std::function<T(void)> fRead; if N==1 and std::function<T(uint32_t)> fRead; if N>1.

Unfortunately I got the compiler error: error: invalid parameter type ‘std::conditional<true, void, unsigned int>::type’ {aka ‘void’}.

The fRead member is initialized with a lambda function (which is not shown in this snipped).

I found some information that void is not a valid type which is not allowed to be used as template argument with std::conditional_t. But unfortunately I don't know how to solve this issue.


Solution

  • void as a parameter to conditional_t works fine in principle, you just have to consider where you end up using it.

    In this case you use it to form function<T(void)> which is invalid.

    An alternative might be:

    using ReadFunction = std::conditional_t<(N == 1), std::function<T()>, std::function<T(uint32_t)>>;
    
    ReadFunction fRead;