#include <iostream>
#include <tuple>
#include <iostream>
#include <utility>
template <std::size_t... Idx>
auto make_index_dispatcher(std::index_sequence<Idx...>)
{
return [](auto&& f) { (f(std::integral_constant<std::size_t, Idx>{}), ...); };
}
template <std::size_t N>
auto make_index_dispatcher()
{
return make_index_dispatcher(std::make_index_sequence<N>{});
}
template <typename Tuple, typename Func>
void for_each(Tuple&& t, Func&& f)
{
constexpr auto n = std::tuple_size<std::decay_t<Tuple>>::value;
auto dispatcher = make_index_dispatcher<n>();
dispatcher([&f, &t](auto idx) { f(std::get<idx>(std::forward<Tuple>(t))); });
}
int main()
{
for_each(std::make_tuple(1, 42.1, "hi"), [](auto&& e) {std::cout << e << ","; });
}
Question 1> Pourquoi je dois utiliser std::integral_constant<std::size_t, Idx>{}
au lieu de simplement Idx
dans l'énoncé suivant ? D'après ce que j'ai compris, std::integral_constant<std::size_t, Idx>
est un type. Est-il vrai que std::integral_constant<std::size_t, Idx>{}
est une valeur de Idx
?
// OK
template <std::size_t... Idx>
auto make_index_dispatcher(std::index_sequence<Idx...>)
{
return [](auto&& f) { (f(std::integral_constant<std::size_t, Idx>{}), ...); };
}
// Erreur
template <std::size_t... Idx>
auto make_index_dispatcher(std::index_sequence<Idx...>)
{
return [](auto&& f) { (f(Idx), ...); };
}
Est-il vrai que std::get
expression constante attendue en temps de compilation alors que Idx
n'est PAS une expression constante en temps de compilation ?
Question 2> Pourquoi nous ne pouvons pas passer std::index_sequence
par référence ?
// Erreur : auto make_index_dispatcher(std::index_sequence<Idx...>&)
Merci.