Lisp like C++ 函数调用 std::tuple 和折叠表达式
Lisp like C++ function calling with std::tuple and fold expressions
关于Lisp,我能想到的最基本的事情就是如何调用函数。对于那些不知道如何在 Lisp 中做到这一点的人来说,是这样的:
(fun1 a b (fun2 c d))
; c and d are parameters to the function fun2,
; and a, b and the result of fun2 are parameters
; to the function fun 1
好吧,我想在 C++ 中使用 std::tuple 和折叠表达式来做类似的事情。基本上,我有一个包含 2 个元素的元组,第一个是我要调用的函数,第二个是另一个带有参数的元组。我能够使这个概念与 1 个函数一起使用,并使用以下代码将“Lisp 元组”放入另一个元组中:
auto add = [](auto ... args){ return (args + ...); };
auto t1_args = std::make_tuple(10, 5);
auto t1 = std::tie(add, t1_args);
auto t_m = std::tie(t1);
auto result = std::apply([](auto ... args){
return (std::apply(std::get<0>(args), std::get<1>(args...)), ...);
}, t_m);
std::cout << result << std::endl; // prints 15
但是我不能用多个函数,多个“Lisp 元组”,一个在另一个里面。这里有人可以帮我吗?也许用另一种方法来制作“Lisp 元组”,但我真的不知道如何让它工作。
您必须递归地评估每个参数,例如:
template <typename T>
auto eval(T t)
{
return t;
}
template <typename ...Ts>
auto eval(std::tuple<Ts...> tuple)
{
return std::apply([](auto... args){ return std::invoke(eval(args)...); }, tuple);
}
Demo.
关于Lisp,我能想到的最基本的事情就是如何调用函数。对于那些不知道如何在 Lisp 中做到这一点的人来说,是这样的:
(fun1 a b (fun2 c d))
; c and d are parameters to the function fun2,
; and a, b and the result of fun2 are parameters
; to the function fun 1
好吧,我想在 C++ 中使用 std::tuple 和折叠表达式来做类似的事情。基本上,我有一个包含 2 个元素的元组,第一个是我要调用的函数,第二个是另一个带有参数的元组。我能够使这个概念与 1 个函数一起使用,并使用以下代码将“Lisp 元组”放入另一个元组中:
auto add = [](auto ... args){ return (args + ...); };
auto t1_args = std::make_tuple(10, 5);
auto t1 = std::tie(add, t1_args);
auto t_m = std::tie(t1);
auto result = std::apply([](auto ... args){
return (std::apply(std::get<0>(args), std::get<1>(args...)), ...);
}, t_m);
std::cout << result << std::endl; // prints 15
但是我不能用多个函数,多个“Lisp 元组”,一个在另一个里面。这里有人可以帮我吗?也许用另一种方法来制作“Lisp 元组”,但我真的不知道如何让它工作。
您必须递归地评估每个参数,例如:
template <typename T>
auto eval(T t)
{
return t;
}
template <typename ...Ts>
auto eval(std::tuple<Ts...> tuple)
{
return std::apply([](auto... args){ return std::invoke(eval(args)...); }, tuple);
}
Demo.