Reputation: 158
I want to use lazy loading of an unordered_map. I search the map for a key. If it exists I use the value. If it doesn't exist I create the value and emplace the key,value pair.
I want to avoid the last map.find() statement - it should be an unnecessary operation (performance is important). It might fail :-( and I'd hope for a better solution.
Note: The calling routine should only have a const reference to value. Avoid instantiation of value in calling routine.
How can I avoid the second lookup AND have a properly scoped const reference returned to the caller ?
h file
` typedef std::vector DataPtrListVector; struct DataCacheStruct { DataPtrListVector dataItemOne; }; typedef boost::unordered_map DataCacheMap; // declare instance variable DataCacheMap dataCacheMap; // declare function const DataCacheStruct& getOrCreateData( const std::string& dataKey,... );`
cpp file
` // Lazy Load of DataStruct unordered_map std::string key = someString; const DataCacheStruct& dataStruct = getOrCreateData( key, ... ); // const DataCacheStruct& class::getOrCreateData( const std::string key, ...) { DataCacheMap::const_iterator itData = dataCacheMap.find(key); if (itData != dataCacheMap.end()) { return itData->second; } DataCacheStruct newData = doSomethingSlow(); dataCacheMap.emplace(std::make_pair(key, newData)); // Now I want to return newData as a const reference, as per unordered_map // but it goes out of scope before the calling routine can use it. DataCacheMap::const_iterator itData = dataCacheMap.find(key); return itData->second; }`
Upvotes: 3
Views: 636
Reputation: 9735
As I've already said, the method emplace
, returns a pair of an iterator to the newly inserted element and a value of true.
You can simply use that iterator, to get a reference:
auto it_new_insertion = dataCacheMap.emplace(std::make_pair(key, newData));
if (it_new_insertion.second == false) {
// something wrong with memory. handle it
}
return it_new_insertion.first->second;
Upvotes: 2