为多个元组的每个第 n 个参数调用 lambda?
Calling a lambda for each nth argument of multiple tuples?
我正在尝试编写一个代码,使用从一组可变元组中提取的输入参数调用 lambda。但是,我的尝试没有编译:
#include <iostream>
#include <tuple>
#include <utility>
#include <type_traits>
template <typename ...>
struct first_of;
template <typename T, typename ... Args>
struct first_of<T, Args...> {
using type = std::decay_t<T>;
};
template <typename T>
struct first_of<T> {
using type = std::decay_t<T>;
};
template <typename ... T>
using first_of_t = typename first_of<T...>::type;
template <typename Fn, typename... Tuples, std::size_t... Idxs>
void run_impl(Fn&& fn, std::index_sequence<Idxs...>, Tuples... t) {
auto temp = {(fn(std::get<Idxs>(t)...), true)...};
(void)temp;
}
template <typename Fn, typename... Tuples>
void run(Fn&& fn, Tuples&&... tuples) {
run_impl(std::forward<Fn>(fn), std::make_index_sequence<std::tuple_size<first_of_t<Tuples...>>::value>{}, std::forward<Tuples>(tuples)...);
}
int main() {
auto a = std::make_tuple(1, 2.34, "one");
auto b = std::make_tuple(32, 5.34, "two");
auto print = [](auto& f, auto& g) { std::cout << f << ", " << g << std::endl; };
run(print, a, b);
}
我期待以下输出:
1, 32
2.34, 5.34
one, two
我使用的是 c++14,很遗憾,没有折叠表达式。
这是代码的神栓 link:https://godbolt.org/z/G19n5z
最简单的方法是添加另一层间接,让 run_impl
委托给另一个执行实际调用的函数。我冒昧地将您的函数重命名为 call_transposed()
:
template <std::size_t I, typename Fn, typename... Tuples>
void call_with_nth(Fn&& fn, Tuples&&... t) {
fn(std::get<I>(std::forward<Tuples>(t))...);
}
template <typename Fn, std::size_t... Idxs, typename... Tuples>
void call_transposed_impl(Fn&& fn, std::index_sequence<Idxs...>, Tuples&&... t) {
auto temp = {(call_with_nth<Idxs>(fn, std::forward<Tuples>(t)...), true)...};
(void)temp;
}
template <typename Fn, typename... Tuples>
void call_transposed(Fn&& fn, Tuples&&... tuples) {
call_transposed_impl(
std::forward<Fn>(fn),
std::make_index_sequence<std::tuple_size<first_of_t<Tuples...>>::value>{},
std::forward<Tuples>(tuples)...);
}
我不确定为什么你的代码不起作用,但我怀疑 std::get<Idxs>(t)...
试图同时扩展两个包 Idxs
和 t
,离开你没有包可以稍后扩展。这段代码一次只处理一个包,从而避免了这个问题。
我正在尝试编写一个代码,使用从一组可变元组中提取的输入参数调用 lambda。但是,我的尝试没有编译:
#include <iostream>
#include <tuple>
#include <utility>
#include <type_traits>
template <typename ...>
struct first_of;
template <typename T, typename ... Args>
struct first_of<T, Args...> {
using type = std::decay_t<T>;
};
template <typename T>
struct first_of<T> {
using type = std::decay_t<T>;
};
template <typename ... T>
using first_of_t = typename first_of<T...>::type;
template <typename Fn, typename... Tuples, std::size_t... Idxs>
void run_impl(Fn&& fn, std::index_sequence<Idxs...>, Tuples... t) {
auto temp = {(fn(std::get<Idxs>(t)...), true)...};
(void)temp;
}
template <typename Fn, typename... Tuples>
void run(Fn&& fn, Tuples&&... tuples) {
run_impl(std::forward<Fn>(fn), std::make_index_sequence<std::tuple_size<first_of_t<Tuples...>>::value>{}, std::forward<Tuples>(tuples)...);
}
int main() {
auto a = std::make_tuple(1, 2.34, "one");
auto b = std::make_tuple(32, 5.34, "two");
auto print = [](auto& f, auto& g) { std::cout << f << ", " << g << std::endl; };
run(print, a, b);
}
我期待以下输出:
1, 32
2.34, 5.34
one, two
我使用的是 c++14,很遗憾,没有折叠表达式。 这是代码的神栓 link:https://godbolt.org/z/G19n5z
最简单的方法是添加另一层间接,让 run_impl
委托给另一个执行实际调用的函数。我冒昧地将您的函数重命名为 call_transposed()
:
template <std::size_t I, typename Fn, typename... Tuples>
void call_with_nth(Fn&& fn, Tuples&&... t) {
fn(std::get<I>(std::forward<Tuples>(t))...);
}
template <typename Fn, std::size_t... Idxs, typename... Tuples>
void call_transposed_impl(Fn&& fn, std::index_sequence<Idxs...>, Tuples&&... t) {
auto temp = {(call_with_nth<Idxs>(fn, std::forward<Tuples>(t)...), true)...};
(void)temp;
}
template <typename Fn, typename... Tuples>
void call_transposed(Fn&& fn, Tuples&&... tuples) {
call_transposed_impl(
std::forward<Fn>(fn),
std::make_index_sequence<std::tuple_size<first_of_t<Tuples...>>::value>{},
std::forward<Tuples>(tuples)...);
}
我不确定为什么你的代码不起作用,但我怀疑 std::get<Idxs>(t)...
试图同时扩展两个包 Idxs
和 t
,离开你没有包可以稍后扩展。这段代码一次只处理一个包,从而避免了这个问题。