簡體   English   中英

在過去的迭代器上插入unordered_map

[英]unordered_map insert on past-the-end iterator

find鍵時,是否通過find返回的通過端迭代器插入的定義和有效行為:

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

因為與使用以下命令相比,這將節省額外的查找:

m[key] = value;

雖然可以安全地將結束迭代器作為提示傳遞給unordered_map::insert ,但實際上並沒有完成任何事情。

在這三種主要的標准庫實現中,只有libstdc ++會使用該提示執行任何操作,即使這樣,如果指向有效條目,它最終也只會使用它。

如果要避免進行兩次查找(一次以確定是否存在該元素,而另一次進行插入),則應嘗試將其插入。 insert返回bool表示是否已插入新元素)和迭代器(用於迭代新插入的元素或阻止插入的現有元素)。 這意味着在不存在的情況下插入元素並對其進行迭代的最有效方法是執行以下操作:

decltype(m)::iterator it;
bool inserted;
std::tie(it, inserted) = m.insert(std::make_pair(key, value));
if (inserted) {
    // ...
}

如果您所mapped_type類型的構建成本很高,則可以避免使用try_emplace (僅適用於C ++ 17或更高版本):

auto [it, inserted] = m.try_emplace(key, args, to, value, constructor);
if (inserted) {
    // ...
}

在C ++ 17之前的版本中,您可以只讓operator[]默認構造元素,然后比較容器大小以確定是否添加了新元素:

size_t size_before = m.size();
ValueType& element = m[key];
size_t size_after = m.size();
if (size_before != size_after) {
    element = ValueType{args, to, value, constructor};
    // ...
}

顯然,這具有默認構造元素且僅使用可分配類型的缺點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM