首页 > 解决方案 > C++ Map使用非默认构造函数初始化对象

问题描述

在 C++ 中,假设我有一个定义如下的无序映射:

unordered_map<int, MyClass> my_map;
auto my_class = my_map[1];

在上面的代码中,如果 my_map 中没有 1 作为键,它将使用默认构造函数初始化 MyClass 并返回。但是有没有办法使用 MyClass 的非默认构造函数进行初始化?

标签: c++

解决方案


你是对的,operator[]需要值类型是默认可构造的。

insert才不是:

std::unordered_map<int, MyClass> my_map;
// Populate the map here

// Get element with key "1", creating a new one
// from the given value if it doesn't already exist
auto result = my_map.insert({1, <your value here>});

这为您提供了一对包含元素的迭代器(无论是创建新的还是已经存在的)和一个布尔值(告诉您是哪种情况)。

所以:

auto& my_class = *result.first;
const bool was_inserted = result.second;

现在你可以用这些信息做任何你想做的事。通常你甚至不会关心result.second,可以忽略它。

对于更复杂的值类型,您可以使用emplace,这就像insert但是,嗯,更好。假设如果不使用该值,您真的不希望构造该值,并且您拥有 C++17:

auto result = my_map.try_emplace(1, <your value's ctor args here here>);

如果您不在乎(或没有 C++17):

auto result = my_map.emplace(1, <your value>);

这仍然比insert它可以将值移动到地图中而不是复制它要好。

最终,如果您甚至不想不必要地生成您的 ctor args,您总是可以先做一个find,但最好尽量避免这种情况,因为插入操作本身也会进行查找。


推荐阅读