Ответ на Вопрос 2 ) Да, возможно, как подсказал @ user253751, мой первоначальный подход (Helper<tpl..., curr>
) правильный, хотя я допустил другую ошибку, которая вызвала вышеупомянутую ошибку в том, что Строка, пропуская «шаблон» после используемого типа. Приведенный ниже код показывает исправление и работает нормально:
#include <cstdint>
#include <tuple>
template <typename... tpl> struct Helper {
template <std::size_t rem, typename curr, typename... rest> struct take {
using tp = Helper<tpl..., curr>;
using type = tp::template take<rem-1, rest...>::type;
};
template <typename curr, typename... rest> struct take<0, curr, rest...> {
using type = std::tuple<tpl...>;
};
};
template <std::size_t s, typename... tpl> using take_t = Helper<>::take<s, tpl...>;
int main() {
take_t<2, int, int, int>::type k = std::make_tuple(1, 2);
}
Ответ на Вопрос 1 дан трюком, выполненным здесь , см. Полный пример здесь . Это возможно, например, с помощью следующей конструкции (адаптированной на примере «на лету» и непроверенной):
template <class tuple> struct foo;
template <class ... args> struct foo<std::tuple<args...> {
// implementation here!
};
, которая очень аккуратна и может быть использована также для integer_sequence (которую я пробовал и не удалось делать до сих пор).
полная реализация того, чего я хотел достичь, гораздо более ясная, чем мой первоначальный подход выше, можно найти здесь :
template <size_t s, typename is, typename ...args> struct thlp;
template <size_t s, size_t... i, class... args> struct thlp<s, std::index_sequence<i...>, args...> {
static_assert(s <= sizeof...(args), "Requested new tuple size exceeds old one.");
using type = std::tuple<std::tuple_element_t<i, std::tuple<args...>>...>;
};
template <size_t s, typename... args>
using conditional_tuple_t = thlp<s, decltype(std::make_index_sequence<s>()), args...>::type;