簡體   English   中英

如何在嵌套的 map 和 c++17 中使用 emplace/insert_or_assign?

[英]How to use emplace/insert_or_assign in nested map with c++17?

如果我有

map<int, map<int, int>> m;

當我需要插入時,我可以使用

m[1] = { {1, 1} };

但是現在我想用 emplace/insert_or_assign 來代替它,我可能會用

m.emplace(1, map<int, int>{ {1, 1} });

但是我覺得寫起來有點復雜,特別是我應該重新寫map<int, int> ,如果原來的map改成比如map<int, map<int, map<int, map<int, int>>>>就更map<int, map<int, map<int, map<int, int>>>> ,那么我應該根據需要重復map<int, int> 那么有沒有更簡單易讀的方法呢?

問題應該是為什么要在第一點使用emplace / insert_or_assign


emplace點是為了讓您在需要之前不要進行不必要的創建。 使用map<int, map<int, int>> ,您可能只想在要插入新的 map 時才創建內部 map。要正確利用這種行為,您應該只提供構建 map 的 arguments,不是 map 本身。

但是,唯一的構造函數map也可以在構造過程中填充容器是采用initializer_list的構造函數。 所以理想情況下你會想寫這樣的東西:

m.emplace(1, {{1, 1}}) // this won't work

但是,這是行不通的,因為emplace無法將{{1, 1}}推斷為initializer_list 這意味着您必須手動指定,例如:

m.emplace(1, std::initializer_list<std::pair<const int, int>>{{1, 1}})

這是相當多的寫作,如果你有更多的嵌套層,那只會更糟。 在這一點上,最好只寫:

if (m.find(1) == m.end()) {
// or `!m.contains(1)` for C++20 or later
    m[1] = {{1, 1}};
}

另一方面,如果你真的不關心不必要的構造,你應該只使用insert代替:

m.insert({1, {{1, 1}}})

insert_or_assign的要點是使 map 適用於不可默認構造的類型。

當您只調用m[1]時,如果m[1]不存在,這將默認構造一個 object。 但是,這也意味着如果類型不是默認可構造的,則operator[]不起作用。

但是,由於map是默認可構造的,因此直接使用operator[]與使用insert_or_assign之間沒有太大區別。 因此,只有 go 使用operator[]

你可以做

typedef map<int, int> mp;

然后做

m.emplace(1, mp{ {1, 1} });

這不那么冗長,也清楚地表明什么是 map 構造函數,什么不是。

希望這可以幫助。

編輯:您也可以嘗試做

template <typename T>
using nest_mp = std::map<int, T>;

typedef std::map<int, int> mp;

並做

m.emplace(1, nest_mp<nest_mp<mp>>>{ {1, { {1, { {1, 1} } } } } };

每個 map 構造都有兩個{大括號 - 一個調用std::map初始化列表構造函數,另一個調用std::pair初始化列表構造函數。

最好根本不要使用map<int, map<int, int>> 相反,使用map<std::pair<int, int>, int 這意味着你有一個組合鍵,所以不是將值存儲在[A][B]中,而是將它存儲在[pair(A, B)]中。 這樣,當您存儲一個值時,它總是為其節點分配一個 memory 分配(因為只有一個映射)。

然后你寫這樣的代碼:

m.emplace(std::make_pair(1, 1), 1);
m.insert_or_assign({1, 1}, 1);

如果你想用鍵中的特定“第一個”integer 迭代值:

int subkey = 1;
for (auto it = m.lower_bound({subkey, 0}),
    end = m.upper_bound({subkey, INT_MAX});
    it != end; ++it)
{
    // do something with elements whose key.first == subkey
}

暫無
暫無

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

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