I have a function that looks like this
template <typename... Rets, typename... Args>
std::tuple<Rets...> call_nn(std::string_view query, Args... args)
{
pqxx::work w(con_);
pqxx::row res = w.exec_params1(pqxx::zview(query), args...);
w.commit();
return // std::tuple<Rets...>((res[std::index_sequence_for<Rets>{}].as<Rets>())...); doesn't work
}
pqxx::row
represents one row of result table from postgres. It supports getting column value as res[0].as<int>()
.
The problem is that I don't know how to expand the variadic template argument to access the type index and the type itself. What should I put instead of ???
?
return std::tuple(ret[/*???*/].as<Rets>()...);
I tried to define int i = 0
and expand like res[i++].as<Rets>()...
but then compiler gives warning
Multiple unsequenced modifications to 'i'
so maybe there are some better ways to expand return statement to something like example below without runtime variables
return std::tuple(ret[0].as<X>(), ret[1].as<Y>(), /*...*/ ret[n].as<Z>() );
You want to create a second parameter pack for the values in index_sequence
:
template <typename... Rets, std::size_t... Idxs, typename... Args>
std::tuple<Rets...> call_nn(std::index_sequence<Idxs...>, std::string_view query, Args&... args)
{
pqxx::work w(con_);
pqxx::row res = w.exec_params1(pqxx::zview(query), args...);
w.commit();
return std::tuple<Rets...>((res[Idxs].as<Rets>())...);
}
template <typename... Rets, typename... Args>
std::tuple<Rets...> call_nn(std::string_view query, Args... args)
{
return call_nn<Rets...>(std::index_sequence_for<Rets...>{}, query, args...);
}