2016-04-26 33 views
1

假設我有一個map<string, vector<int>>,名爲my_map,我想將42與密鑰"foo"關聯。從Java未來我希望有做這樣的事情添加到具有可變值的地圖

if (my_map.find("foo") != my_map.end()) { 
    my_map["foo"].push_back(42); 
} else { 
    vector<int> my_vector; 
    my_map["foo"] = my_vector; 
    my_vector.push_back(42); 
} 

出乎我的意料,我發現我可以做

my_map["foo"].push_back(42); 

這是如何工作的?如果地圖值的類型沒有沒有參數的構造函數,my_map["foo"]會做什麼?假設你想以除使用空構造函數以外的方式初始化所有值?在Java中,我可以做

map.computeIfAbsent("foo", **some supplier of Vectors**).add(42); 

C++中是否有等價物?

+2

'vector my_vector; my_map [「foo」] = my_vector; my_vector.push_back(42);'在你的'else'中,你想要做什麼? –

+0

容器存儲副本。 C++不是Java,並非所有東西都是參考.... – user463035818

+0

我認爲會發生什麼事情是,當您嘗試插入元素(如果未找到「foo」)時會創建新的地圖單元格。在創建期間向量的默認構造函數被稱爲已經爲您創建一個空矢量 – Stefano

回答

6

my_map["foo"]默認構造一個新的值,如果它尚不存在。因此,如果值類型不是default-constructible(即沒有沒有參數的構造函數),則會導致編譯錯誤。然後,您就必須做到以下幾點:

my_map.emplace("foo", param).first->second.push_back(42); 

emplace將從param構建自己的價值,如果它不存在。

更多參數可以與分段構造從std::pair提供:

my_map.emplace(
    std::piecewise_construct, 
    std::forward_as_tuple("foo"), 
    std::forward_as_tuple(param1, param2, param3) 
).first->second.push_back(42); 
2

您可以閱讀hereoperator[]

如果k沒有在容器匹配任何元素的關鍵,該函數將使用該鍵插入一個新元素並返回對其映射值的引用。請注意,即使沒有爲元素分配映射值(該元素使用其默認構造函數構造),它始終會將容器大小增加1。

如果mapped_type沒有默認構造函數,則會出現編譯錯誤。