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 c 17 compiler support, using if constexpr
template<typename T>
void Set(const T& data)
{
if constexpr (areAllowedTypes<T, Types...>) m_data = data;
}