I have a static_loop
construct like this
template void static_loop(F&& f) {
static_assert(n <= 8 &a
Change
template <typename T>
constexpr size_t tupleSize(T) { return tuple_size_v<T>; }
to:
template <typename T>
constexpr size_t tupleSize(T const&) { return tuple_size_v<T>; }
That is, take the argument by reference to const, not by value. As-is, you're trying to copy a non-constexpr tuple in a constant expression - that can't work. By reference is fine since you're not actually reading the tuple.
Suggestion: try with
// .........VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
static_loop<std::tuple_size_v<decltype(ab)>>([&](auto i) { std::get<i>(ab) = i; });
I mean... you can't use ab
(as value), in a constant expression, because ab
isn't defined constexpr
.
And you can't define it constexpr
because it's initialized using std::ref()
that isn't constexpr
.
But you're not interested in ab
as value to get the size of its type; you're interested only in ab
type; so you can pass through decltype(ab)
.
-- EDIT --
Off Topic suggestion.
Instead of static_loop()
, you can use the classic way based on std::index_sequence
(and template folding, available starting from C++17).
I mean... if you define a run_1()
function (with run_1_helper()
helper) as follows
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...>{}); }
you can write A
as follows
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;
}
};
Or, maybe better, simply using std::apply()
, as follows
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;
}
};