2016-04-28 54 views
4

爲什麼這段代碼不能編譯?直接在std :: map的映射對

std::map<int,std::pair<int,int>> m; 
m.emplace(1,1,1); 

假設我們可以編輯std::map::emplace代碼,是有可能改變它,以使上面的代碼合法嗎?

回答

8

它是完全一樣的理由無效,這是無效的:

std::pair<const int, std::pair<int, int>> p{1, 1, 1}; 

因爲上面是,在本質上,地圖的emplace歸結爲。

要使其工作,你可以使用piecewise_construct constructor of std::pair,這是引入正是爲此目的:

m.emplace(
    std::piecewise_construct, 
    std::forward_as_tuple(1), 
    std::forward_as_tuple(1, 1) 
); 

這將有沒有要求任何不必要的構造函數(即使他們很可能會被省略的預期效果)。


爲了回答你有關使「直接」語法工作假設性的問題:在一般情況下對任意map<K, V>,沒有。想象一下:

struct Proof { 
    Proof(int); 
    Proof(int, int); 
}; 

std::map<Proof, Proof> m; 
m.emplace(1, 1, 1); // Now what? 

當然能它的map<T, std::pair<T, T>>有限的情況下工作。在海量的高級模板技巧的幫助下(想想SFINAE左邊,右邊和中間,然後是一些),這可能適用於更普通的事情。這是否值得,取決於你的情況的細節。

+0

在一般情況下,您還需要您的類來支持分段構造函數 –