簡體   English   中英

將空向量放入std :: map()

[英]Emplace empty vector into std::map()

如何將空向量放置到std::map 例如,如果我有一個std::map<int, std::vector<int>> ,並且我想要map[4]包含一個空的std::vector<int> ,那我該怎么稱呼?

如果使用operator[](const Key&) ,則當您訪問不存在的元素時,映射將自動放置一個值初始化 (例如,在std::vector的情況下為default-constructed )。 看這里:

http://en.cppreference.com/w/cpp/container/map/operator_at

(由於C ++ 11,細節有些復雜,但是在您的情況下,這很重要)。

這意味着,如果您的地圖是空的,並且您執行map[4] ,它將很容易為您提供對空(默認構造)矢量的引用。 盡管可以使您的意圖更加清楚,但不必分配空向量。

演示: https//godbolt.org/g/rnfW7g

不幸的是,嚴格正確的答案的確是使用std::piecewise_construct作為第一個參數,然后是兩個元組。 第一個代表創建鍵(4)的參數,第二個代表創建向量的參數(空參數集)。

它看起來像這樣:

map.emplace(std::piecewise_construct,   // signal piecewise construction
            std::make_tuple(4),         // key constructed from int(4)
            std::make_tuple());         // value is default constructed

當然,這看起來很難看,其他替代方法也可以使用。 他們甚至可以在優化的版本中不再生成任何代碼:

從概念上講,此調用了默認構造和移動分配,但優化器很可能會看到它。

map.emplace(4, std::vector<int>());

這將調用默認構造,然后是復制分配。 但同樣,優化器可能會完全了解它。

map[4] = {};

為了確保將空矢量放置在位置4上,您可以簡單地嘗試clear位置4上的矢量。

std::map<int, std::vector<int>> my_map;
my_map[4].clear();

正如其他人提到的那樣,如果std::map的索引運算符不存在,則它將在指定的索引處構造一個空值。 在這種情況下,調用clear是多余的。 但是,如果std::vector<int>已經存在,則調用clear可以清除那里的向量,從而導致一個空向量。

這可能比我以前分配給{}方法更有效(請參閱下文),因為我們可能計划在位置4的向量上添加元素,並且我們不為此付出任何新分配的費用。 另外,如果my_map[4]先前用法表示將來的用法,那么我們的新向量最終可能會被調整為與以前幾乎相同的大小,這意味着我們節省了重新分配的成本。


以前的方法:

只需分配給{} ,容器就應該在那里正確構造一個空向量:

std::map<int, std::vector<int>> my_map;
my_map[4] = {};
std::cout << my_map.size() << std::endl; // prints 1

演示版

編輯:如Jodocus所述,如果您知道std::map在位置4處尚未包含vector ,則僅嘗試訪問該位置處的向量將默認構造一個,例如:

std::map<int, std::vector<int>> my_map;
my_map[4]; // default-constructs a vector there

最簡單的解決方案怎么了? std::map[4] = {};

在現代C ++中,這應該沒有任何開銷,或者至少很少有開銷。

如果必須使用emplace ,我能想到的最好的解決方案是:

std::map<int, std::vector<int>> map;
map.emplace(4, std::vector<int>());

將piecewise_construct與std :: make_tuple一起使用:

map.emplace(std::piecewise_construct, std::make_tuple(4), std::make_tuple());

我們在位置4插入一個空向量。

如果有一般情況,將大小為100的向量填充為10,則:

map.emplace(std::piecewise_construct, std::make_tuple(4), std::make_tuple(100, 10));

piecewise_construct :此常量值作為構造對對象的第一個參數傳遞,以選擇構造函數形式,該形式通過將兩個元組對象的元素轉發到各自的構造函數來就地構造其成員。

暫無
暫無

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

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