tuple_element再考

using type_impl<Indices, Types>::value...;がミソ。

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

#include <type_traits>
#include <utility>

extern void* enabler;

template <typename T>
struct identity {
    using type = T;
};

template <std::size_t N, typename T>
struct type_impl {
    template <std::size_t I, std::enable_if_t<I == N>*& = enabler>
    static T value();
};

template <typename... Types>
struct tuple_impl;
template <std::size_t... Indices, typename... Types>
struct tuple_impl<std::index_sequence<Indices...>, Types...> : type_impl<Indices, Types>... {
    using type_impl<Indices, Types>::value...;
    
    template <std::size_t I>
    using type = typename decltype(tuple_impl<std::index_sequence<Indices...>, Types...>::template value<I>())::type;
};

template <typename... Types>
struct tuple : tuple_impl<std::make_index_sequence<sizeof...(Types)>, identity<Types>...> {};

template <std::size_t N, typename T>
struct tuple_element {
    using type = typename T::template type<N>;
};
template <std::size_t N, typename T>
using tuple_element_t = typename tuple_element<N, T>::type;

int main() {
    using t = tuple<const int, char*, void>;
    static_assert(std::is_same_v<const int, tuple_element_t<0, t>>);
    static_assert(std::is_same_v<char*, tuple_element_t<1, t>>);
    static_assert(std::is_same_v<void, tuple_element_t<2, t>>);
}