Home > OS >  a concept to check if at least one of the type in a list of types can be constructed from a given ty
a concept to check if at least one of the type in a list of types can be constructed from a given ty

Time:12-26

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.

failed attempt

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>>());

Demo

  • Related