Search code examples
c++c++17lazy-initialization

How to lazy initialize a map using std::optional, and add to it using emplace


I have a class with a std::optional map, the reasoning here is that a map is expensive to construct so I'm looking for ways to minimize the impact. As the map is not always used, the thinking is why construct it until it IS used.

I'm having trouble with adding values to the class after construction, the syntax eludes me :), or perhaps I misunderstood some limitation and it can't actually be used this way. Some insight would be appreciated.

class A {
public:
void addValues() {
_map_value.emplace(/* what goes here ?*/);
// It is expecting something like std::enable_if_t<std::is_constructible<std::map< .... initializer list
}
private:
std::optional<std::map<std::string, ResourceValue>> _map_value{};
};

I've tried making pair's and various forms of emplace. I see i'm supposed to use std::optional::emplace, but I think this is just for construction, not for accessing and adding to the map afterwards. How can I manage this map after its been optionally constructed?


Solution

  • std::optional<T>::emplace takes a number of arguments and invokes the constructor of T with those arguments to construct the managed value in place. In this case it doesn't take any parameters, because you wouldn't pass any parameters to the constructor of map.

    Maybe check beforehand if the optional is already initialized or not and then access the managed object with ->:

    if(!_map_value) {           // if the optional is empty
        _map_value.emplace();   // construct
        _map_value->insert(...); // Do stuff with the map
    }