我有一个函数f(a,b),它接受两个输入。我事先不知道将使用a和b的哪个值。我不介意在内存上有点浪费(我关心速度)。我希望能够检查f(a,b)的输出是否已经交付,如果已经交付,则在不重新运行f(a,b)进程的情况下再次交付该输出。
在Python语言中使用装饰器很容易做到这一点,但是C++在这里对我来说太难了。
发布于 2012-04-12 03:37:35
我会使用关键字为std::pair的std::map (或者可能是std::unordered_map),或者可能使用地图的映射。
在这种情况下,C++11的改进可能会有所帮助。或者是一些助推器之类的。
发布于 2012-04-12 04:14:46
发帖者问:
我希望能够检查f(a,b)的输出是否已经被传递,如果已经传递,不需要重新运行f(a,b)过程,就可以再次传递该输出。,
。
使用std::map在C++中实现起来非常简单。该函数恰好有两个参数,这意味着我们可以使用std::pair来描述它们。
#include <map>
#include <iostream>
uint64_t real_f(int a, int b) {
std::cout << "*";
// Do something tough:
return (uint64_t)a*b;
}
uint64_t memo_f(int a, int b) {
typedef std::pair<int, int> key;
typedef std::map<key, uint64_t> map;
static map m;
key k(a,b);
map::iterator it = m.find(k);
if(it == m.end()) {
return m[k] = real_f(a, b);
}
return it->second;
}
int main () {
std::cout << memo_f(1, 2) << "\n";
std::cout << memo_f(3, 4) << "\n";
std::cout << memo_f(1, 2) << "\n";
std::cout << memo_f(3, 4) << "\n";
std::cout << memo_f(5, 6) << "\n";
}上述程序的输出为:
*2
*12
2
12
*30没有星号的线条表示缓存的结果。
发布于 2012-04-12 03:55:30
有了C++11,你可以使用任务和未来。让f作为您的函数:
int f(int a, int b)
{
// Do hard work.
}然后,您将调度函数执行,它将返回返回值的句柄。此句柄称为“将来”
template <typename F>
std::future<typename std::result_of<F()>::type>
schedule(F f)
{
typedef typename std::result_of<F()>::type result_type;
std::packaged_task<result_type> task(f);
auto future = task.get_future();
tasks_.push_back(std::move(task)); // Queue the task, execute later.
return std::move(future);
}然后,您可以使用此机制,如下所示:
auto future = schedule(std::bind(&f, 42, 43)); // Via std::bind.
auto future = schedule([&] { f(42, 43); }); // Lambda alternative.
if (future.has_value())
{
auto x = future.get(); // Blocks if the result of f(a,b) is not yet availble.
g(x);
}免责声明:我的编译器不支持任务/未来,因此代码可能有一些粗糙的边缘。
https://stackoverflow.com/questions/10112693
复制相似问题