A compact one returning a lambda:
template <typename R, typename... Args>
std::function<R (Args...)> memo(R (*fn)(Args...)) {
std::map<std::tuple<Args...>, R> table;
return [fn, table](Args... args) mutable -> R {
auto argt = std::make_tuple(args...);
auto memoized = table.find(argt);
if(memoized == table.end()) {
auto result = fn(args...);
table[argt] = result;
return result;
} else {
return memoized->second;
}
};
}
In C++14, one can use generalized return type deduction to avoid the extra indirection imposed by returning std::function
.
Making this fully general, permitting passing arbitrary function objects without wrapping them in std::function
first is left as an exercise for the reader.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…