博客文章Automatic Memoization in c++0x提供了生成现有功能的记忆版本的功能。博客文章和相关代码之前已经在stackoverflow(例如What does this C++11 code do?)中讨论过,但是,这些解决方案都不能提供能够正确记忆递归函数的完全通用记忆器。支持递归功能的自动记忆功能
当然,也有改变,通过使用像这样的递归调用的伎俩(假设我们有一个memoizer比如在博客中提出的一个已经在地方叫memoize
):
std::function<int (int)> f;
int fib(int n) {
if (n < 2) return n;
return f(n-1) + f(n-2);
}
int main(void) {
f = memoize(std::function<int (int)>(fib));
}
但这种感觉更像是一种解决方法,而不是一个合适的解决方案,因为我们仍然需要访问我们想要记忆的功能。一个合适的解决方案应该能够完全记忆任何功能,包括某些库中定义的功能。然而,生产这样的解决方案似乎超出了我的范围(假设它是可能的),因此我在问:
是否可以实现真正的通用记忆功能?
如何可以实现这样的壮举?
如果这是不可能的,是否至少有一种方法来推广上述方法。沿(不编译和无效C++)线的东西:
int fib(int n){
if (n < 2) return n;
return this_func(n-1) + this_func(n-2);
}
哪里this_func
是一些东西,类似于this
指针一类的,但对于一个功能。 [编辑:这可能仍然从问题的困扰,该this_func
指针将指向fib
代替memoized fib
]
我不认为今天有什么办法做到这一点,特别是预编译的库。我的第一个猜测是,在事实之后添加记忆的方法是使用链接器用memoized_fib()包装函数替换fib()的重定位。然而,我不知道编译和链接阶段的细节,以了解内部递归在链接阶段是否可用于替换。哦,我不知道有一个链接器可以做这种替换。 – Speed8ump
如果您希望递归调用使用相同的缓存,我认为您需要以某种方式在它们之间共享缓存。也就是说,要么使用'static'(更好,但更慢:'thread_local')缓存或将缓存作为附加参数传递。无论哪种方式都需要修改'fib'。 ([wikipedia]上的一个例子](https://en.wikipedia.org/wiki/Fixed_point_combinator#Explanation_for_imperative_programmers),它使用后一种技术,通过函数的memoized版本将缓存作为参数传递。) – dyp