[英]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.