在过去的迭代器上插入unordered_map

时间:2019-06-12 04:20:07

标签: c++ c++11 iterator unordered-map

在找不到密钥时,是否通过find返回的通过端迭代器插入的已定义且有效的行为:

auto it = m.find(key);
if (it == m.end()) {
    m.insert(it, make_pair(key, value));
}

因为与以下方式相比,这将节省额外的查找:

m[key] = value;

1 个答案:

答案 0 :(得分:2)

尽管可以安全地将结束迭代器作为提示传递给 While .Busy DoEvents Wend While .ReadyState <> 4 DoEvents Wend ,但实际上并没有完成任何事情。

在三个主要的标准库实现中,只有libstdc ++会执行带有该提示的任何操作,即使这样,它只有在指向有效条目时才会使用它。

如果要避免进行两次查找(一次以确定是否存在该元素,而另一次进行插入),则应尝试将其插入。 unordered_map::insert既返回表示已插入新元素的insert,又返回对新插入的元素或阻止插入的现有元素的迭代器。这意味着如果不存在则插入元素并对其进行迭代的最有效方法是执行以下操作:

bool

如果您的decltype(m)::iterator it; bool inserted; std::tie(it, inserted) = m.insert(std::make_pair(key, value)); if (inserted) { // ... } 的构建成本很高,则可以避免使用mapped_type进行构建(仅在C ++ 17或更高版本中可用):

try_emplace

在C ++ 17之前的版本中,您只需让auto [it, inserted] = m.try_emplace(key, args, to, value, constructor); if (inserted) { // ... } 默认构造该元素并比较容器的大小,以确定是否添加了新元素:

operator[]

显然,这样做的缺点是默认构造了元素,并且只能使用可分配的类型。