Учитывая std::tuple<A, B, ...> foo
, есть ли какая-либо универсальная (шаблонная) функция или методика в C ++ 14 для получения нового кортежа std::tuple<B, ...> bar
, который содержит все элементы, кроме первого foo
?Или, может быть, что-то в Boost?
Я написал вспомогательную функцию, используя пакеты параметров и некоторые шаблоны метапрограммирования, чтобы сделать это, но я бы хотел выбросить все эти вещи!
Вот что я сейчас делаю.Я определяю вспомогательную функцию unshift_tuple()
, которая возвращает кортеж, содержащий все, кроме первого элемента кортежа, переданного в функцию.Реализация unshift_tuple()
использует вспомогательную функцию unshift_tuple_with_indices()
, которая принимает пакет параметров, содержащий индексы кортежа, для извлечения;вспомогательный тип sequential_integer_list
используется для генерации соответствующего пакета параметров списка индексов с использованием шаблонного метапрограммирования.Гадкий!
#include <tuple>
template <size_t... Integers>
struct integer_list {};
template <size_t N, size_t... Args>
struct sequential_integer_list : sequential_integer_list<N - 1, N - 1, Args...> {};
template <size_t... Args>
struct sequential_integer_list<0, Args...> { typedef integer_list<Args...> type; };
template <typename FirstElement, typename... Elements, size_t... Indices>
static std::tuple<Elements...> unshift_tuple_with_indices(
const std::tuple<FirstElement, Elements...>& tuple,
integer_list<Indices...> index_type)
{
return std::make_tuple(std::get<Indices + 1>(tuple)...);
}
template <typename FirstElement, typename... Elements>
std::tuple<Elements...>
unshift_tuple(const std::tuple<FirstElement, Elements...>& tuple)
{
return unshift_tuple_with_indices(tuple,
typename sequential_integer_list<sizeof...(Elements)>::type());
}
int main(int, char *[])
{
std::tuple<int, std::string, double> foo(42, "hello", 3.14);
std::tuple<std::string, double> bar = unshift_tuple(foo);
}
Для ясности, этот код работает просто отлично.Я просто очень хочу удалить его (или любую его часть) и использовать вместо него что-нибудь встроенное, если это возможно!
Edit
Jarod42 указал на существование std::integer_list
в C ++ 14, который упрощает реализацию до чего-то вроде:
#include <cstddef>
#include <tuple>
#include <utility>
template <typename T1, typename... T, size_t... Indices>
std::tuple<T...> unshift_tuple_with_indices(
const std::tuple<T1, T...>& tuple, std::index_sequence<Indices...>)
{
return std::make_tuple(std::get<Indices + 1>(tuple)...);
}
template <typename T1, typename... T> std::tuple<T...>
unshift_tuple(const std::tuple<T1, T...>& tuple)
{
return unshift_tuple_with_indices(tuple,
std::make_index_sequence<sizeof...(T)>());
}