Most of the time I just do this:
template<typename T>concept TupleLike = requires{std::tuple_size<T>::value;};// Can't use `std::tuple_size_v` as it's not SFINAE-friendly.
If something else is missing, you'll get a hard error, yes. But I don't see it as a problem, since arguably a type with an incomplete implementation of the tuple protocol is broken anyway.
One thing to note is that you must use using std::get;
get<i>(t)
instead of std::get<i>(t)
to support user-defined types that have get()
in their namespace rather than in std::
. This is what C++17 structured bindings do internally.