Если я правильно понимаю, вы просто хотите создать новый кортеж, содержимое которого является результатом функции, примененной к содержимому старого кортежа?Вот так:
std::tuple<A,B,C> result =
std::tuple<A,B,C>(f(std::get<0>(x), f(std::get<1>(x), f(std::get<2>(x));
Это правильно?Чтобы ответить на это, я краду отличный индексатор кортежей @Luc Danton.В самом сердце эта конструкция позволяет нам написать:
std::tuple<Args...> result = std::tuple<Args...>(f(std::get<Indices>(x))...);
Вот как это работает: во-первых, Indices
помощник:
#include <tuple>
template<int... Indices>
struct indices {
typedef indices<Indices..., sizeof...(Indices)> next;
};
template<int Size>
struct build_indices {
typedef typename build_indices<Size - 1>::type::next type;
};
template<>
struct build_indices<0> {
typedef indices<> type;
};
template<typename Tuple>
typename build_indices<std::tuple_size<typename std::decay<Tuple>::type>::value>::type
make_indices()
{
return {};
}
Теперь для приложения: мы простосоздадим простую фиксированную функцию f
, которая удваивает ввод.
template <typename T> T f(const T & t) { return 2*t; }
Давайте применим это к кортежу.Вот встроенная функция, но вы можете легко создать шаблон, который на f
:
template <typename Tuple, int ...Indices>
Tuple apply_f_impl(const Tuple & x, indices<Indices...>)
{
return Tuple(f(std::get<Indices>(x))...);
}
template <typename Tuple>
Tuple apply_f(const Tuple & x)
{
return apply_f_impl(x, make_indices<Tuple>());
}
Наконец, контрольный пример:
#include <iostream>
#include "prettyprint.hpp"
int main()
{
std::tuple<int, double, char> x(5, 1.5, 'a');
auto y = apply_f(x);
std::cout << "Before: " << x << ", after: " << y << std::endl;
}
Все кредиты для этого должны идти к Люку, которыйпридумали индексатор кортежей с самоиндексированием.