Home > Back-end >  Emplacing an std::pair of strings to an unordered map reusing the string's heap
Emplacing an std::pair of strings to an unordered map reusing the string's heap

Time:02-19

I have an unordered map of string-pairs that i reference via a message id (key). Now I want to construct the string pair in place using the temporary string objects that the function receives, hence reusing the memory already allocated for the string on the heap. But I'm having difficulty wrapping my head around this construction. Here is what I came up with:

std::unordered_map<int, std::pair<std::string, std::string>> data_map;

void foo(int msg_id, std::string&& topic, std::string&& data)
{
    data_map.emplace(std::piecewise_construct, std::forward_as_tuple(msg_id), std::forward_as_tuple(std::piecewise_construct, std::forward_as_tuple(topic), std::forward_as_tuple(data)));
}

My reasoning says that I need to construct a first pair for the map containing key and value of which the value must be created by another piecewise pair constructor to which I feed the r-value refs. It compiles but my gut feeling tells me something is off. Will I be able to reuse the allocated heap memory of the string like this?

CodePudding user response:

Your construction is not using the move constructor to construct the new strings, thereby it is not reusing allocations.

The names of variables are always lvalues. Therefore std::forward_as_tuple will forward topic and data as lvalue reference, causing use of the copy constructor for the strings.

To pass rvalues, you need std::move. Also, since std::pair has a constructor which takes two arguments for the two pair elements, which are exactly the two strings you already have, you don't need the second piecewise construction:

data_map.emplace(std::piecewise_construct, std::forward_as_tuple(msg_id), std::forward_as_tuple(std::move(topic), std::move(data)));
  • Related