在C ++中是否有一种处理递归函数的首选方法,每次都重用一个未更改的对象?例如(伪代码):
void func(HashMap h, Logger logger, int depth)
{
// Do stuff then call func recursively...
func(h, logger, depth+1);
}
因此,我们在几个对象(哈希映射和记录器)中传递的每个调用都保持不变。是的,我们可以通过引用传递但它仍然看起来效率低下并且看起来不太漂亮。我能想到的唯一选择是全局变量或在结构中捆绑常量参数。
答案 0 :(得分:2)
你所描述的是一个封闭的词汇环境,也就是一个关闭"关闭"。这个概念存在"免费"在像Lisp和Scheme这样的动态语言中,"放过lambda" pattern允许您捕获函数中的变量并使用它们,即使它们的封闭范围已经消失或退出。
您可以使用struct
作为捕获变量的容器来模拟C ++中的闭包,并将函数(仿函数)应用于struct
。最常见的模式通常是使用operator()
的方式:
struct my_closure {
Hashmap &hmap_;
Logger &logger_;
int depth_;
my_closure(Hashmap &hmap, Logger &logger, int depth) :
hmap_(hmap), logger_(logger), depth_(depth)
{ }
void operator()(void)
{ /* do stuff here, including recurse */ }
};
这将拯救你的唯一一件事是在堆栈上推送额外的东西,这在循环方面不一定能为你节省太多(结构的1个结构参考[this
指针]与2引用+ 1整数。)如果你的编译器支持尾递归,这可能是一个好处,但会牺牲可读性。
答案 1 :(得分:0)
这是完全干净的代码,可以准确地表达正在发生的事情。当然,在C ++中,您应该将HashMap和Logger作为const引用传递。
从性能的角度来看,制作这两个对象类变量可能会更好。但这可能会使代码更难理解,所以如果你真的遇到性能问题就去做。
顺便说一下,如果函数没有修改HashMap并返回void,那么该函数是做什么的?