Здесь очень приятно (не мой) пример того, как и можно расширить (или «взрываются») кортеж в качестве аргументов функции:«распаковать» станд :: массив <T,N>, как аргументы функции
template<int ...I> struct index_tuple_type {
template<int N> using append = index_tuple_type<I..., N>;
};
template<int N> struct make_index_impl {
using type = typename make_index_impl<N-1>::type::template append<N-1>;
};
template<> struct make_index_impl<0> { using type = index_tuple_type<>; };
template<int N> using index_tuple = typename make_index_impl<N>::type;
template <typename I, typename ...Args>
struct func_traits;
template <typename R, int ...I, typename ...Args>
struct func_traits<R, index_tuple_type<I...>, Args...> {
template <typename TT, typename FT>
static inline R call(TT &&t, FT &&f) {
return f(std::get<I>(std::forward<TT>(t))...);
}
};
template<
typename FT,
typename ...Args,
typename R = typename std::result_of<FT(Args&&...)>::type
>
inline R explode(std::tuple<Args...>& t, FT &&f) {
return func_traits<R, index_tuple<sizeof...(Args)>, Args...>
::call(t, std::forward<FT>(f));
}
, то вы можете использовать это как так:
void test1(int i, char c) {
printf("%d %c\n", i, c);
}
int main() {
std::tuple<int, char> t1{57, 'a'};
explode(t1, test1);
}
Я бродил, как вы могли бы сделать то же самое с std::array
поскольку оно совсем как кортеж. std::get<N>
работает с std::array
, поэтому я подумал, что было бы легко изменить это решение. Но что-то вроде этого не работает:
template<
typename FT,
typename Arg,
std::size_t I,
typename R = typename std::result_of<FT(Arg&&)>::type
>
inline R explode(std::array<Arg, I>& t, FT &&f) {
return func_traits<R, index_tuple<I>, Arg>::
call(t, std::forward<FT>(f));
}
void test2(int i1, int i2) {
printf("%d %d\n", i1, i2);
}
int main() {
std::array<int, int> t1{1, 2};
explode(t2, test1);
}
из части std::result_of<FT(Arg&&)>::type
. Аргумент типа Arg&&
неверен и result_of
не имеет поля type
. Для кортежа Args&&...
расширен, но теперь он должен быть «повторен» I
раз. Есть ли способ сделать это, используя result_of
, чтобы возвращаемый тип можно было вычесть?
Также мне было интересно, имея инструменты, чтобы «распаковать» tuple
и array
было бы возможно «распаковать» рекурсивно (возможно, с использованием enable_if
) структуры, как tuple<array<int, 2>, tuple<array<double,3>, ...
и так далее? Какое-то дерево, где tuple
и array
- ветки, а другие - листья?
'std :: forward' с ссылкой lvalue, закодированной как аргумент шаблона типа, равный« no-op ». и вы, вероятно, хотели поставить 't' в качестве своего аргумента. и btw, используйте [trailing return type like here] (http://coliru.stacked-crooked.com/a/5af1aac65ba014d9) вместо –
Вы считали вместо этого выполнение функции, которая скрывает массив до кортежа ссылок? – Hurkyl
@PiotrS. исправил, что 'forward', мой плохой расширяющийся макрос ошибочно. @Hurkyl Да, я подумал об этом, но это не так. –