Предлагам друго решение, наистина различно от кода във въпроса, което според мен е много по-ефективно (създаване само на един std::array
; блендер, получен чрез последователност от индекси на шаблони)
#include <array>
#include <utility>
#include <iostream>
template <typename T, std::size_t I0>
int blenderH (double t, T const & arr, std::index_sequence<I0> const &)
{ return arr[I0]; }
template <typename T, std::size_t I0, std::size_t ... Is>
auto blenderH (double t, T const & arr,
std::index_sequence<I0, Is...> const &)
-> std::enable_if_t<0U != sizeof...(Is), int>
{ return (1-t) * blenderH(t, arr, std::index_sequence<(Is-1U)...>{})
+ t * blenderH(t, arr, std::index_sequence<Is...>{}); }
template <typename ... Args>
int blender (double t, Args ... as)
{
static constexpr auto size = sizeof...(Args);
return blenderH(t, std::array<int, size>{ { as... } },
std::make_index_sequence<size>{});
}
int main()
{ std::cout << blender(.3, 23, 42, 89) << std::endl; }
За съжаление и това решение работи (std::index_sequence
и std::make_index_sequence
), като се започне от C++14.
-- РЕДАКТИРАНЕ --
Калет казва.
Някакво обяснение на случващото се тук би помогнало. Объркан съм от липсата на I0
в тялото на второто претоварване.
Опитвам се с обяснение.
Да предположим, че се нарича рекурсивна версия на BlenderH()
(второто претоварване) със списък от индекси в стойността std::index_sequence
. Кажете 5, 6, 7 и 8; така че I0
е 5
и Is...
е 6, 7, 8
.
Трябва да извикаме рекурсивно blenderH()
с индекси 5, 6, 7
първо и с 6, 7, 8
следващо.
Можем да избегнем използването на I0
(5
), защото
5, 6, 7
се получава от 6, 7, 8
намаляване с 1 на всяка стойност (така че std::index_sequence<(Is-1U)...>
за първото рекурсивно повикване)
и 6, 7, 8
е Is...
без модификации (така че std::index_sequence<Is...>
във втория.
От практическа гледна точка I0
се обявява само за изхвърляне; няма нужда да го използвате.
person
max66
schedule
17.12.2017