Предложение: попробуйте с
// .........VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
static_loop<std::tuple_size_v<decltype(ab)>>([&](auto i) { std::get<i>(ab) = i; });
Я имею в виду ... вы не можете использовать ab
(в качестве значения) в постоянном выражении, потому что ab
не определено constexpr
.
И вы не можете определить его constexpr
, потому что он инициализирован с использованием std::ref()
, который не constexpr
.
Но вас не интересует ab
как значениеполучить размер своего типа;вас интересует только тип ab
;так что вы можете пройти через decltype(ab)
.
- РЕДАКТИРОВАТЬ -
Не по теме.
Вместо static_loop()
, вы можетеиспользуйте классический способ, основанный на std::index_sequence
(и сворачивании шаблонов, начиная с C ++ 17).
Я имею в виду ... если вы определите функцию run_1()
(с помощником run_1_helper()
) какследует
template <typename F, typename ... Ts, std::size_t ... Is>
void run_1_helper (F const & f, std::tuple<Ts...> & t, std::index_sequence<Is...> const)
{ (f(std::get<Is>(t), Is), ...); }
template <typename F, typename ... Ts>
void run_1 (F const & f, std::tuple<Ts...> & t)
{ run_1_helper(f, t, std::index_sequence_for<Ts...>{}); }
Вы можете написать A
следующим образом
struct A {
int a;
int b;
void run() {
auto ab = std::make_tuple(std::ref(a), std::ref(b));
run_1([](auto & v, auto i){ v = i; }, ab);
std::cout << a << " " << b << std::endl;
}
};
Или, может быть, лучше, просто используя std::apply()
, как следует
struct A {
int a;
int b;
void run() {
auto ab = std::make_tuple(std::ref(a), std::ref(b));
int i { -1 };
std::apply([&](auto & ... vs){ ((vs = ++i), ...); }, ab);
std::cout << a << " " << b << std::endl;
}
};