I'd like to create a concept for tuple-like types. A tuple-like type would be something that, like std::pair
, std::tuple
and std::array
, offers a compile time known number of types accessible through a compile time indexed get<size>
function.
I am new to concepts and I do not know where to start. Unfortunately, the STL seems not to have such a concept in the <concepts>
header.
For example, I can write:
template<typename T>
concept tuple_like = requires(T value)
{
std::invoke(get<0>, value);
};
But I am not sure how to generalize that 0
to be any index.
The standard defines exposition only concept pair-like
and has-tuple-element
in [range.subrange] and [range.elements.view] respectively, we can extend them to the tuple-like
concept:
template<class T, std::size_t N>
concept has_tuple_element =
requires(T t) {
typename std::tuple_element_t<N, std::remove_const_t<T>>;
{ get<N>(t) } -> std::convertible_to<const std::tuple_element_t<N, T>&>;
};
template<class T>
concept tuple_like = !std::is_reference_v<T>
&& requires(T t) {
typename std::tuple_size<T>::type;
requires std::derived_from<
std::tuple_size<T>,
std::integral_constant<std::size_t, std::tuple_size_v<T>>
>;
} && []<std::size_t... N>(std::index_sequence<N...>) {
return (has_tuple_element<T, N> && ...);
}(std::make_index_sequence<std::tuple_size_v<T>>());
Please be sure to check out P2165R2 which also defines a similar tuple-like
concept.
I think, a tuple-like type is a class for which both std::tuple_size
and std::get
are defined.
Here is an example of how this can be conceptualized:
#include <tuple>
#include <array>
template<typename T>
concept TupleLike =
requires (T a) {
std::tuple_size<T>::value;
std::get<0>(a);
};
template<TupleLike T>
void foo(T t);
std::tuple<int, char> t1;
std::array<int, 10> a1;
void bar()
{
foo(t1); // OK
foo(a1); // OK
foo("Hello"); //Fails
}
Please note, this will fail for empty tuples, which might be what you want, or might not.
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.