Конечно, это выполнимо.
Давайте дадим тренировку std::integer_sequence
, std::tuple
и соответствующему оборудованию.
Во-первых, укажите способполучить индекс единственного уникального соответствия для произвольного типа в виде кортежа:
template <class T, class U, std::size_t... N>
static constexpr auto tuple_index_impl(std::index_sequence<N...>) noexcept {
static_assert((std::size_t() + ... + std::is_same_v<T, std::tuple_element_t<N, U>>) == 1,
"There is no single exact match");
return (0 + ... + (N * std::is_same_v<T, std::tuple_element_t<N, U>>));
}
template <class T, class U>
static constexpr std::size_t
tuple_index_v = tuple_index_impl<T, U>(std::make_index_sequence<std::tuple_size_v<U>>());
Жаль, что это уже не часть стандартной библиотеки.
Далее, используйте это дляполучить все индексы и поместить их в std::array
:
template <class T, class U, std::size_t... N>
constexpr auto indices_impl(std::index_sequence<N...>) noexcept {
return std::array<std::size_t, sizeof...(N)>{tuple_index_v<std::tuple_element_t<N, U>, T>...};
}
template <class T, class U>
constexpr auto indices() noexcept {
return indices_impl<T, U>(std::make_index_sequence<std::tuple_size_v<U>>());
}
Пример использования:
for (auto x : indices<t1, t2>())
std::cout << x << '\n';
Посмотреть в прямом эфире на колиру .