I have a list of types TypeList
. I am currently using a tuple to hold these types.
What I want is the following:
Given a new type X
- check if at least one of the type from TypeList
can be constructed from X
. Also I want to use existing concept std::constructible_from
I started with the following concepts definitions:
template <typename From, typename To, std::size_t... Is>
concept ConstructibleFromHelper = requires(From from, To to) {
requires (std::constructible_from<typename std::tuple_element<Is, To>::type,From> || ...);
};
template <typename From, typename To>
concept ConstructibleFrom = requires {
requires ConstructibleFromHelper<From,To,std::make_index_sequence<std::tuple_size_v<To>>()>;
};
But I am getting the following error:
./type_traits.h:36:46: error: template argument for non-type template parameter is treated as function type 'std::make_index_sequence<std::tuple_size_v<To>> ()' (aka '__make_integer_seq<std::integer_sequence, unsigned long, std::tuple_size_v<To>> ()')
requires ConstructibleFromHelper<From,To,std::make_index_sequence<std::tuple_size_v<To>>()>;
Looks, like partial specialization of ConstructibleFromHelper
is required to expand make_index_sequence
to std::size_t... Is
. But concept does not support partial specialisation.
How to make this work with tuple
typelist and std::constructible_from
.
If this does not work, please suggest any other method to achieve the same result.
Thanks.
CodePudding user response:
You can do this with an immediately-invoked lambda, i.e. by expanding the tuple
's elements directly in the function body
template <typename From, typename To>
concept ConstructibleFrom = []<std::size_t... Is>(std::index_sequence<Is...>) {
return (std::constructible_from<std::tuple_element_t<Is, To>, From> || ...);
}(std::make_index_sequence<std::tuple_size_v<To>>());