将 std::pair 个字符串放置到无序映射中,重新使用字符串的堆
Emplacing an std::pair of strings to an unordered map reusing the string's heap
我有一个无序的字符串对映射,我通过消息 ID(键)引用它。现在我想使用函数接收的临时字符串对象就地构造字符串对,从而重用已经为堆上的字符串分配的内存。但是我很难理解这个结构。这是我想出的:
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)));
}
我的推理是我需要为包含键和值的映射构建第一对,其中的值必须由另一个分段对构造函数创建,我向其提供右值引用。它可以编译,但我的直觉告诉我有些地方不对劲。我可以像这样重用分配给字符串的堆内存吗?
您的构造没有使用移动构造函数来构造新字符串,因此它没有重用分配。
变量名总是左值。因此 std::forward_as_tuple
将转发 topic
和 data
作为左值引用,导致使用字符串的复制构造函数。
要传递右值,您需要 std::move
。此外,由于 std::pair
有一个构造函数,它为两个对元素接受两个参数,这正是你已经拥有的两个字符串,你不需要第二个分段构造:
data_map.emplace(std::piecewise_construct, std::forward_as_tuple(msg_id), std::forward_as_tuple(std::move(topic), std::move(data)));
我有一个无序的字符串对映射,我通过消息 ID(键)引用它。现在我想使用函数接收的临时字符串对象就地构造字符串对,从而重用已经为堆上的字符串分配的内存。但是我很难理解这个结构。这是我想出的:
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)));
}
我的推理是我需要为包含键和值的映射构建第一对,其中的值必须由另一个分段对构造函数创建,我向其提供右值引用。它可以编译,但我的直觉告诉我有些地方不对劲。我可以像这样重用分配给字符串的堆内存吗?
您的构造没有使用移动构造函数来构造新字符串,因此它没有重用分配。
变量名总是左值。因此 std::forward_as_tuple
将转发 topic
和 data
作为左值引用,导致使用字符串的复制构造函数。
要传递右值,您需要 std::move
。此外,由于 std::pair
有一个构造函数,它为两个对元素接受两个参数,这正是你已经拥有的两个字符串,你不需要第二个分段构造:
data_map.emplace(std::piecewise_construct, std::forward_as_tuple(msg_id), std::forward_as_tuple(std::move(topic), std::move(data)));