问题是,Cache
缓存的对象本身没有解决您的问题,否则它将毫无用处。
a 的想法Cache
是避免一些计算,因此索引将是计算的参数,如果已经存在,它将直接映射到结果。
现在,您实际上可能需要第二个索引来从缓存中删除对象,但这不是强制性的。当然还有其他可用的策略。
如果您真的想在应用程序中的其他任何地方没有使用对象时立即从缓存中删除它们,那么您可以有效地使用二级索引。虽然这里的想法是根据T*
, not进行索引weak_ptr<T>
,但要保留weak_ptr<T>
,因为否则您无法shared_ptr
在相同的引用计数上创建新的。
确切的结构取决于计算的参数在事后是否难以重新计算,如果是,一个简单的解决方案是:
template <typename K, typename V>
class Cache: boost::enable_shared_from_this<Cache>
{
typedef std::map<K, boost::weak_ptr<V>> KeyValueMap;
typedef std::map<V*, KeyValueMap::iterator> DeleterMap;
struct Deleter {
Deleter(boost::weak_ptr<Cache> c): _cache(c) {}
void operator()(V* v) {
boost::shared_ptr<Cache> cache = _cache.lock();
if (cache.get() == 0) { delete v; return; }
DeleterMap::iterator it = _cache.delmap.find(v);
_cache.key2val.erase(it->second);
_delmap.erase(it);
delete v;
}
boost::weak_ptr<Cache> _cache;
}; // Deleter
public:
size_t size() const { return _key2val.size(); }
boost::shared_ptr<V> get(K const& k) const {
KeyValueMap::const_iterator it = _key2val.find(k);
if (it != _key2val.end()) { return boost::shared_ptr<V>(it->second); }
// need to create it
boost::shared_ptr<V> ptr(new_value(k),
Deleter(boost::shared_from_this()));
KeyValueMap::iterator kv = _key2val.insert(std::make_pair(k, ptr)).first;
_delmap.insert(std::make_pair(ptr.get(), kv));
return ptr;
}
private:
mutable KeyValueMap _key2val;
mutable DeleterMap _delmap;
};
请注意特别困难:指针可能比 . 长Cache
,所以我们需要一些技巧......
供您参考,虽然这似乎可行,但我对这段代码一点信心都没有:未经测试,未经证实,bla,bla ;)