3

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;
    }`
1
  • emplace returns the iterator where the element has been inserted Commented Sep 17, 2016 at 9:50

1 Answer 1

2

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;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.