简体   繁体   中英

C++20 Concept to check tuple-like types

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

Demo.

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.

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