簡體   English   中英

STL 容器 find_or_create()

[英]STL container find_or_create()

是否有某種 STL 工具可以在 STL 容器上執行find_or_create()

例如,在 unordered_map 的情況下,我經常發現自己需要檢索一些值並在不存在值時創建它。 有很多函數可以有條件地插入 map,但所有這些函數都會立即創建一個新值,即使 map 中已經存在一個值:

#include <iostream>
#include <unordered_map>

struct A {
        A() = default;

        A(std::string_view method) {
                std::cout << "Created via " << method << std::endl;
        }
};

int main() {
        std::unordered_map<int, A> m{
                {0, A{}}
        };

        // Get a reference to m[0]; create it if it doesn't exist
        // Key 0 is already in the map, so these calls *should* do little work
        auto &val1 = *m.insert(std::make_pair(0, A{"insert"})).first;
        auto &val2 = *m.emplace(0, A{"emplace"}).first;
        auto &val3 = *m.emplace(std::piecewise_construct,
                        std::make_tuple(0),
                        std::make_tuple("piecewise construct")).first;
        auto &val4 = *m.try_emplace(0, A{"try_emplace"}).first;
        auto &val5 = (m[0] = A{"operator[]"});

        return 0;
}

Output:

Created via insert
Created via emplace
Created via piecewise construct
Created via try_emplace
Created via operator[]

如果 object A的創建成本很高(需要很長時間來構建、獲取系統資源等),這些不必要的創建可能是不可取的。 這經常導致我創建一個這樣的模板:

#include <iostream>
#include <unordered_map>

struct A {
        A() = default;

        A(std::string_view method) {
                std::cout << "Created via " << method << std::endl;
        }
};

template<class Map, class OnCreate>
typename Map::mapped_type &find_or_create(Map &map, const typename Map::key_type &key, const OnCreate &on_create) {
        auto it = map.find(key);
        if (it == map.end())
                it = map.emplace(key, on_create(key)).first;
        return it->second;
}

int main() {
        std::unordered_map<int, A> m;

        // Get a reference to m[0]; create it if it doesn't exist
        auto &val1 = find_or_create(m, 0, [](const int &) { return A{"find_or_create"}; });
        auto &val2 = find_or_create(m, 0, [](const int &) { return A{"never created"}; });
        return 0;
}

Output:

Created via find_or_create

有沒有更好(即更簡單)的方法來通過 STL 實現這一點,或者像這樣的模板是 go 的方法嗎?

try_emplace是你想要的。 您的問題是您故意構造A ,而不是將arguments傳遞給構造函數,它可能會或可能不會用於構造A

你想要的是這樣的:

auto &val4 = *m.try_emplace(0, "try_emplace").first;

如果您無法通過構造函數調用創建 object(即:通過工廠函數或其他方式創建實例),您的查找或創建 function 將很有用。

暫無
暫無

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

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