2016-04-28 59 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

在一般情况下,您还需要您的类来支持分段构造函数 –