Home > Blockchain >  Passing template parameter pack to type_traits and std::enable_if
Passing template parameter pack to type_traits and std::enable_if

Time:08-17

I'm trying to create a class holding std::variant with a member function that would only accept types held by the nested variant object. That function works basically the same way as variant's operator=. However, the question is - how do I use std::enable_if and type_traits together with template parameter pack?

The example below (attempting to check if any of the Types is constructible from T) obviously doesn't compile:

template<typename... Types>
class Wrapper
{
public:
    template<typename T, std::enable_if_t<std::is_constructible_v<Types..., T>, bool> = true>
    void Set(const T& data) {
        m_data = data;
    }

private:
    std::variant<Types...> m_data;
};

int main()
{
    Wrapper<int, float> wrapper;
    wrapper.Set(123);
    return 0;
}

CodePudding user response:

How do I use std::enable_if and type_traits together with template parameter pack?

You might do as follows:

#include <type_traits>

template<typename T, typename... Types>
inline constexpr bool areAllowedTypes = (std::is_constructible_v<T, Types> && ...);
// && -> if all the types must be convertable, otherwise use ||

now

template<typename T>
auto Set(const T& data) ->std::enable_if_t<areAllowedTypes<T, Types...>>
{
    m_data = data;
}

Or since you have compiler support, using if constexpr

template<typename T>
void Set(const T& data)
{
    if constexpr (areAllowedTypes<T, Types...>)  m_data = data;
}
  • Related