Вам нужно взять индекс времени выполнения и поднять его в константное выражение. Самый простой способ сделать это - просто использовать Boost.Mp11 , который поставляется с функцией только для этого:
template<typename... Args>
class Processor {
std::tuple<Args...> tup;
// call mutate on the ith tuple element
void process(size_t i) {
mp_with_index<sizeof...(Args)>(i, [&](auto I){
mutate(std::get<I>(tup));
});
}
}
Что делает mp_with_index
, так это принимает константное выражение дляМаксимальный размер (sizeof...(Args)
) и размер среды выполнения (i
), а затем вызовите ваш вызываемый (лямбда) с интегральной константой, которая является размером среды выполнения, возведенным в константу-выражение.
Это можно реализовать самостоятельно, используя std::index_sequence
, создав массив указателей на функции и затем вызвав правильный:
template <size_t... Is, typename F>
decltype(auto) mp_with_index(size_t i, F f, std::index_sequence<Is...>) {
using R = decltype(f(std::integral_constant<size_t, 0>{}));
using P = R(*)(F&);
static constexpr P fns[] = {
+[](F& f) -> R { return f(std::integral_constant<size_t, Is>{}); }...
};
return fns[i](f);
}
template <size_t N, typename F>
decltype(auto) mp_with_index(size_t i, F f) {
return mp_with_index(i, f, std::make_index_sequence<N>());
}
(обратите внимание, что реализация Boost.Mp11 лучше, чем эта, этопросто функционально правильно).