История изменений
Исправление Siborgium, (текущая версия) :
Вообще, у тебя что-то не так с дизайном. Ты из стека (lifo) делаешь очередь (fifo). Кроме того, у тебя в дизайне заложено, что храниться будут гетерогенные типы – это действительно необходимо?
Можно сделать так
template <typename T, std::size_t ... I>
auto pop_(T & tuple, std::index_sequence<I...>) {
constexpr auto N = std::tuple_size_v<T>;
((std::get<N - I - 1>(tuple) = popOne()), ...);
}
auto popMany() {
constexpr auto N = sizeof...(Rs);
constexpr auto seq = std::make_index_sequence<N>{};
std::tuple<Rs...> t;
pop_(t, seq);
return t;
}
// later
std::cout << std::get<0>(tuple) << ' ' << std::get<1>(tuple) << ' ' << std::get<2>(tuple) << '\n'; // 5 6 7
Но это подразумевает наличие дефолтного конструктора и move/copy-assignment оператора (впрочем, последнее можно заменить свапом).
Способа развернуть действительно нет (он нужен был бы не у index_sequence, а непосредственно у параметр пака), это неприятно. Есть вариант создавать промежуточный тупл, который потом разворачивать. Это снимет требования выше (останется только необходимость наличия move-ctor), но это лишние действия.
Исходная версия Siborgium, :
Вообще, у тебя что-то не так с дизайном. Ты из стека (lifo) делаешь очередь (fifo). Кроме того, у тебя в дизайне заложено, что храниться будут гетерогенные типы – это действительно необходимо?
Можно сделать так
template <typename T, std::size_t ... I>
auto pop_(T & tuple, std::index_sequence<I...>) {
constexpr auto N = std::tuple_size_v<T>;
((std::get<N - I - 1>(tuple) = popOne()), ...);
}
auto popMany() {
constexpr auto N = sizeof...(Rs);
constexpr auto seq = std::make_index_sequence<N>{};
std::tuple<Rs...> t;
pop_(t, seq);
return t;
}
// later
std::cout << std::get<0>(tuple) << ' ' << std::get<1>(tuple) << ' ' << std::get<2>(tuple) << '\n'; // 5 6 7
Но это подразумевает наличие дефолтного конструктора и move/copy-assignment оператора (впрочем, последнее можно заменить свапом).