简体   繁体   中英

Passing template parameter pack to type_traits and std::enable_if

I am 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 contractible 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;
}

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM