【发布时间】:2015-10-16 19:11:21
【问题描述】:
我对@987654321@ 的问题很感兴趣,所以我不得不尝试一下,因为它让我想起了我非常喜欢的 lisp。该问题的示例:
auto list = [](auto ...xs) {
return [=](auto access) { return access(xs...); };
};
auto length = [](auto xs) {
return xs([](auto ...z) { return sizeof...(z); });
};
int main()
{
std::cout << length(list(1, '2', "3")); // 3
}
最终我得到了一些更多的多态 lambda,这进一步使它看起来像 lisp:
auto l = list(-1, 2, 3, 4, 5, 6);
cons(unary::map(unary::inc)
(binary::map(binary::add)
(cdr(l), 1)), list(12, 13, 14, 15, 16)))
// just an example, it doesn't really look that much like lisp, but still I was amused
现在,如果我想要一个打印功能,我确实做到了,我必须这样写:
auto print = [](auto i)
{
std::cout << i << " ";
return i;
};
然后将其映射到参数包中的每个参数。
这并不是真正的 lisp,我想知道是否有一种方法可以使用 lisp 中使用的 car/cdr 样式递归地遍历参数包。显然,必须使用 list lambda 返回的闭包。
另外,我知道参数包不应该真正用于这样的事情。
编辑:
我设法使用模板实现递归打印:
template<typename First>
void print_helper(First f)
{
std::cout << f << std::endl;
}
template<typename First, typename... Rest>
void print_helper(First f, Rest... r)
{
std::cout << f << " ";
print_helper(r...);
}
template<typename Lambda>
void print(Lambda l)
{
l([=](auto... elements)
{
print_helper(elements...);
});
}
但是现在我遇到了返回值的递归函数的问题。假设我想要一个 filter/remove-if 函数,它返回满足所提供谓词给出的要求的元素列表。目前我正在为每个元素使用一个 std::pair (就像在链接的问题中一样),其中包含一个标志,如果在打印时应该跳过该对。有没有办法在不需要标志的情况下实际只返回那些元素的列表?
【问题讨论】:
-
那么,您要查找的用法是
print (l)whereauto l = list (-1, 2, 3, 4, 5, 6),还是只是print (1,2,3)? -
我更新了原始问题,因为我设法使打印递归。虽然我确定我已经尝试过相同的方法,但出现了一些编译器错误。