C++ 通用可插入缓存模式?

C++ 通用可插入缓存模式?,c++,design-patterns,caching,d,C++,Design Patterns,Caching,D,鉴于它是其中之一,有人知道一种建立可插入缓存策略的方法吗 我想的是,我可以编写一个程序,对需要缓存的内容考虑很少(例如,使用某种锅炉板、低/无成本模式,在我可能需要缓存的任何地方编译成零)然后,当事情进一步发展,我知道我需要缓存的地方时,我可以在不进行侵入性代码更改的情况下添加缓存 作为我正在寻找的解决方案的一个想法;我正在使用(但是中音C++)很好,我喜欢模板。 我想到的最接近的是纯粹函数的记忆化。 您可能还对这本书感兴趣,这本书中有缓存模式。您可能会对如何使用不同的存储和缓存后端实现这类功能

鉴于它是其中之一,有人知道一种建立可插入缓存策略的方法吗

我想的是,我可以编写一个程序,对需要缓存的内容考虑很少(例如,使用某种锅炉板、低/无成本模式,在我可能需要缓存的任何地方编译成零)然后,当事情进一步发展,我知道我需要缓存的地方时,我可以在不进行侵入性代码更改的情况下添加缓存


作为我正在寻找的解决方案的一个想法;我正在使用(但是中音C++)很好,我喜欢模板。

我想到的最接近的是纯粹函数的记忆化。
您可能还对这本书感兴趣,这本书中有缓存模式。

您可能会对如何使用不同的存储和缓存后端实现这类功能感兴趣。简而言之,它提供了一个接口,父应用程序可以使用该接口与MySQL、memcached等进行交互。

我不确定解决方案在多大程度上必须是“通用的”和“可插入的”,但如果您能负担得起对缓存使用的重构(用直接使用某些变量替换函数调用),然后考虑以下内容:

//works for any CopyConstructible type of cache and any function 
//which result should be cached 
//(the arguments of the function have to be properly binded)
/**
* caching + lazy initialization
* we shouldn't allow copying of lazy<T>, because every copy initializes its own cache
* and this is not what intended most of the time
* T must be CopyConstructible
*/
template<class T>
class lazy: private boost::noncopyable
{
public:
    lazy(boost::function0<T> _creator)
        : creator(_creator) {}
    /**
    * aka is_cashed
    */
    bool is_initialized()
    {
        return val;
    }
    operator T&()
    {
        if(!val)
            val = creator();
        return *val;
    }
    T& operator*()
    {
        if(!val)
            val = creator();
        return *val;
    }
    /**
    * resets cache to update it next time it is used
    */
    void reset()
    {
        val.reset();
    }
private:
    boost::function0<T> creator;
    boost::optional<T> val;
};
//usage
    //initialize caching and updating strategy
    lazy<WebPage> cached_page(boost::bind(&Server::getPage, server));
    server->OnPageUpdate = boost::bind(&OnPageUpdate, cached_page);
    .....

    //use cached_page everywhere as if it were regular variable of WebPage type
    showPage(cached_page);
//--------------
void OnPageUpdate(lazy<WebPage>& page)
{
    page.reset();
}
//适用于任何可复制的缓存类型和任何函数
//应该缓存哪个结果
//(函数的参数必须正确绑定)
/**
*缓存+延迟初始化
*我们不应该允许复制lazy,因为每个副本都初始化自己的缓存
*而这并不是大多数时候的意图
*T必须是可复制的
*/
模板
类:私有boost::不可复制
{
公众:
懒惰(boost::function0\u创建者)
:creator(_creator){}
/**
*阿卡被兑现了
*/
bool已初始化()
{
返回val;
}
算子T&()
{
如果(!val)
val=创建者();
返回*val;
}
T&运算符*()
{
如果(!val)
val=创建者();
返回*val;
}
/**
*重置缓存以在下次使用时更新它
*/
无效重置()
{
val.reset();
}
私人:
boost::function0创建者;
boost::可选val;
};
//用法
//初始化缓存和更新策略
惰性缓存页面(boost::bind(&Server::getPage,Server));
服务器->OnPageUpdate=boost::绑定(&OnPageUpdate,缓存的页面);
.....
//到处使用缓存的页面,就好像它是网页类型的正则变量一样
显示页面(缓存页面);
//--------------
void OnPageUpdate(延迟和页面)
{
page.reset();
}

如果要删除延迟初始化,请进行修改,以便在构造函数和方法reset()中创建缓存。

有一个c++0x解决方案用于通用自动备忘录(请参见此处的答案:)

缓存什么类型的东西?哪里就目前而言,这个问题毫无意义。尼尔,这个问题对我来说意义重大。也许这应该被标记为“通用编程”?@Neil。缓存函数的返回值。除此之外,不要做任何假设:它可能是一个纯函数,也可能不是。它可能是从数据库或网页加载数据,或者只是从本地磁盘加载数据,或者只是动态计算数据。它甚至可能是无法缓存的内容(判断值是否过时的唯一方法是再次获取值)或不缓存。一个解决方案必须能够以任何组合处理上述任何和所有问题。@BCS这句话不应该成为问题的一部分吗?简而言之,我说的是“假设我没有说什么”。我真的需要添加它吗?这可能很有趣,但我考虑的更多的是应用程序内部。