如何避免将const-ref返回缓存中的临时性
How to avoid returning const-ref to a temporary in a cache
我有一个简单的对象缓存:
class ObjectCache
{
public:
ObjectCache() {}
const Object& object(const std::string &key) const
{
auto it = cache_.find(key);
if (it != cache_.end())
{
return it->second;
}
return Object(); // const-ref to temporary
}
void insert(const std::string &key, const Object &object)
{
cache_[key] = object;
}
private:
std:map<std::string, Object> cache_;
};
返回类型是从缓存中检索的是const Ref。
但是,在没有找到密钥的情况下,返回了临时的const Ref,并导致调用代码的不确定行为。
如何解决将const ref返回临时的问题?
我有一些想法:
- 插入和返回指针(缓存获得所有权),未找到的nullptr
- 提供objectCache ::包含
- 维护静态对象或空对象成员,并在找不到时返回引用
理想的解决方案是维护当前的缓存,但将指针返回给参考:
class ObjectCache
{
public:
ObjectCache() {}
const Object* object(const std::string &key) const
{
auto it = cache_.find(key);
if (it != cache_.end())
{
return &(it->second);
}
return nullptr;
}
void insert(const std::string &key, const Object &object)
{
cache_[key] = object;
}
private:
std:map<std::string, Object> cache_;
};
这具有避免在堆和内存管理上创建对象的额外好处,但允许呼叫代码与未找到的NULLPTR一起使用。
您可以提供允许呼叫者表达所需行为的接口:
#include <map>
#include <string>
#include <stdexcept>
#include <boost/optional.hpp>
struct Object {};
struct NoObject : std::logic_error
{
using std::logic_error::logic_error;
};
class ObjectCache
{
public:
ObjectCache() {}
/// Require an object for the corresponding key
/// @param key
/// @exception NoObject if the key does not represent an object
/// in cache
const Object& require(const std::string &key) const
{
auto it = cache_.find(key);
if (it != cache_.end())
{
return it->second;
}
throw NoObject(key);
}
/// return the object corresponding to key if it exists
/// If not, call the factory function, store the result and return
/// the corresponding object
template<class Factory>
const Object& acquire(const std::string &key, Factory&& factory)
{
auto it = cache_.find(key);
if (it == cache_.end())
{
it = cache_.emplace(key, factory(key)).first;
}
return it->second;
}
/// Return the object corresponding to key if it exists.
boost::optional<const Object&> query(const std::string &key) const
{
auto it = cache_.find(key);
if (it != cache_.end())
{
return it->second;
}
else
{
return {};
}
}
void insert(const std::string &key, const Object &object)
{
cache_[key] = object;
}
private:
std::map<std::string, Object> cache_;
};
int main()
{
ObjectCache cache;
// fetch existing or create
auto& x = cache.acquire("foo", [](std::string const& key){
return Object();
});
// fetch existing or exception
auto& y = cache.require("foo");
// fetch existing if exists
if(auto z = cache.query("foo"))
{
auto&& zz = z.get();
}
}
相关文章:
- cmake更新缓存的变量
- 试图对缓存进行跨步测试,但程序并没有结束
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- 通过ccmake在cmake中缓存依赖选项
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- 如何使缓存线程安全
- 存储指令是否会阻止缓存未命中的后续指令?
- 缓存局部性与函数调用
- Qt 网页程序集缓存
- 多线程减慢程序速度:无错误共享,无互斥锁,无缓存未命中,无小工作量
- std::shared_ptr vs std::make_shared:意外的缓存未命中和分支预测
- 多个 rocksdb 实例:使用单个共享缓存还是多个独立缓存?
- 无法链接 LRU 缓存C++
- 空函数的参数是否加载到缓存中?
- 是否可以检查变量是否位于 L1/L2/L3 缓存中
- dynamic_cast每次调用是否比具有空检查的缓存变量更昂贵?
- C++:如何在从给定缓存中排除数字的同时生成随机数
- 如何对0,1,..中的k个随机数进行采样..,n-1,而不缓存到数组
- 缓存大量回调,然后批量调用它们,无需v表成本
- 如何避免将const-ref返回缓存中的临时性