Слишком поздно играть?
По сути, мне нужен способ перебора значений из пакета параметров по индексу (индексная часть важна, даже если в этом примере это не требуется).
Извините, но ... как насчет старого доброго использования std::make_index_sequence
и std::index_sequence
?
Поддерживая ваше value_by_index()
, я предлагаю следующее решение на C ++ 14 на основена traverse()
с traverse_helper()
template <typename F, std::size_t ... Is, typename ... VTs>
void traverse_helper (F f, std::index_sequence<Is...>, VTs ... vs)
{
using unused = int[];
(void)unused { 0, (f(value_by_index<Is>(vs...)), 0)... };
}
template <typename F, typename ... VTs>
void traverse (F f, VTs ... vs)
{ traverse_helper(f, std::make_index_sequence<sizeof...(VTs)>{}, vs...); }
Обратите внимание, что я передал также вызываемый объект в качестве параметра.
Если вы можете использовать C ++ 17 (как вы отметили), traverse_helper()
просто становится
template <typename F, std::size_t ... Is, typename ... VTs>
void traverse_helper (F f, std::index_sequence<Is...>, VTs ... vs)
{ (f(value_by_index<Is>(vs...)), ...); }
Вы можете позвонить traverse()
следующим образом
traverse([](auto x){ std::cout << x << std::endl; },
0.0f, 1, 3.33, "str");
Ниже приведен полный пример компиляции C ++ 14
#include <iostream>
#include <tuple>
#include <type_traits>
template <std::size_t I, typename ... As>
auto value_by_index (As && ... as) noexcept
{ return std::get<I>(std::forward_as_tuple(std::forward<As>(as)...)); }
template <typename F, std::size_t ... Is, typename ... VTs>
void traverse_helper (F f, std::index_sequence<Is...>, VTs ... vs)
{
using unused = int[];
(void)unused { 0, (f(value_by_index<Is>(vs...)), 0)... };
}
template <typename F, typename ... VTs>
void traverse (F f, VTs ... vs)
{ traverse_helper(f, std::make_index_sequence<sizeof...(VTs)>{}, vs...); }
int main ()
{
traverse([](auto x){ std::cout << x << std::endl; },
0.0f, 1, 3.33, "str");
}