这是关于堆栈溢出的这问题的一种跟进.
我编写了以下文章来利用回忆录来实现接受单个参数并返回值的函数:
#include <iostream>
#include <map>
using namespace std;
template <class T, class R, R (*Func)(T)>
R memoized(T in) {
static std::map<T,R> memo;
typename std::map<T,R>::iterator found = memo.find(in);
if (found != memo.end()) { return found->second; }
std::cout << "not found" << std::endl; // only for demo
R res = Func(in);
memo[in] = res;
return res;
}
double test(double x){return x*x;}
double test2(double x){return x;}
int main() {
std::cout << memoized<double,double,test>(1) << std::endl;
std::cout << memoized<double,double,test>(1) << std::endl;
std::cout << memoized<double,double,test>(1) << std::endl;
std::cout << std::endl;
std::cout << memoized<double,double,test2>(1) << std::endl;
std::cout << memoized<double,double,test2>(1) << std::endl;
std::cout << memoized<double,double,test2>(1) << std::endl;
return 0;
}产出:
not found
1
1
1
not found
1
1
1这是一个很强的限制,它只适用于接受单个参数的函数,但现在还可以。这种方法还有什么问题吗?
PS:这是故意只使用预C++11
发布于 2016-09-20 20:04:30
我会将memoized更改为与函子类型一起工作,并使用一种特性方法来推断返回类型和参数类型。
template <typename Functor>
typename Functor::R memoized(typename Functor::T in) {
using T = typename Functor::T;
using R = typename Functor::R;
static std::map<T,R> memo;
typename std::map<T,R>::iterator found = memo.find(in);
if (found != memo.end()) { return found->second; }
std::cout << "not found" << std::endl; // only for demo
R res = Functor()(in);
memo[in] = res;
return res;
}
struct Test1
{
using T = double;
using R = double;
R operator()(T x) { return x*x; }
};
struct Test2
{
using T = double;
using R = double;
R operator()(T x) { return x; }
};我使用函子的理由是它简化了用户代码。
int main() {
std::cout << memoized<Test1>(1) << std::endl;
std::cout << memoized<Test1>(1) << std::endl;
std::cout << memoized<Test1>(1) << std::endl;
std::cout << std::endl;
std::cout << memoized<Test2>(1) << std::endl;
std::cout << memoized<Test2>(1) << std::endl;
std::cout << memoized<Test2>(1) << std::endl;
return 0;
}https://codereview.stackexchange.com/questions/141961
复制相似问题