C++ 对map::emplace的语法感到困惑

C++ 对map::emplace的语法感到困惑,c++,c++11,stl,C++,C++11,Stl,给定 std::map myMap; 以下哪项陈述 std::map<int, int> myMap; myMap.emplace(1,2); myMap.emplace({1,2}); myMap.emplace(std::make_pair(1,2)); 是有效的,为什么?在我看来,第二个(带有{}s)如果第三个有效,那么它肯定会起作用。myMap.emplace(1,2)不是无效的,对我来说可以正常工作 myMap.emplace({1,2})无效,因为emplace转发

给定

std::map myMap;
以下哪项陈述

std::map<int, int> myMap;
myMap.emplace(1,2);
myMap.emplace({1,2});
myMap.emplace(std::make_pair(1,2));
是有效的,为什么?在我看来,第二个(带有
{}
s)如果第三个有效,那么它肯定会起作用。

myMap.emplace(1,2)不是无效的,对我来说可以正常工作

myMap.emplace({1,2})无效,因为
emplace
转发它的参数是在适当的位置创建对象,而不是将类型为
value\u类型的对象本身作为参数(来自映射)。由于它不接受目标类型的对象(std::pair
),编译器无法使用初始值设定项列表创建该对象

如果通过调用
emplace
直接构建
std::pair
,您将根本无法从
emplace
中获益,而且它的存在几乎毫无意义

myMap.emplace(std::make_pair(1,2))有效,但可能不是您想要的。你想要

myMap.emplace(1, 2);
myMap.emplace({1, 2});
myMap.emplace(std::make_pair<int,int>(1,2));

由于
emplace
在您已经拥有
std::pair
myMap.emplace(1,2)时不会提供任何好处不是无效的,对我来说可以正常工作

myMap.emplace({1,2})无效,因为
emplace
转发它的参数是在适当的位置创建对象,而不是将类型为
value\u类型的对象本身作为参数(来自映射)。由于它不接受目标类型的对象(std::pair
),编译器无法使用初始值设定项列表创建该对象

如果通过调用
emplace
直接构建
std::pair
,您将根本无法从
emplace
中获益,而且它的存在几乎毫无意义

myMap.emplace(std::make_pair(1,2))有效,但可能不是您想要的。你想要

myMap.emplace(1, 2);
myMap.emplace({1, 2});
myMap.emplace(std::make_pair<int,int>(1,2));


由于
emplace
在您已经拥有
std::pair

myMap.emplace(1,2)时不会提供任何好处不是无效的,对我来说很好。为什么第二个无效?哪个编译器
emplace
不适用于g++4.6.1或更高版本的AFAIKg++4.8.1和clang++3.3
myMap.emplace(1,2)不是无效的,对我来说很好。为什么第二个无效?哪个编译器
emplace
不适用于g++4.6.1或更高版本的AFAIKg++4.8.1和clang++3.3
{1,2}
(基本上调用构造函数,对吧?)和
std::make_pair(1,2)
之间的区别是什么?不,我错了,
{>{1,2}
的演绎根本失败。根据[temp.Decrete.call]/1,它是一个非推断上下文。@ThirtyThree四十
{1,2}
调用什么的构造函数?这就是问题所在,这就是为什么它不起作用。编译器无法转发
{1,2}
,直到最后确定要构造的类型。@DyP我认为这就是为什么无法转发它的原因,因为
初始值设定项\u list
@thirty340 make\u pair创建了一对,而myMap::value\u type是一对,因此,它将需要额外的转换来复制元素,然后才能将其存储在映射中。可能对ints不重要;对于更昂贵的类型来说,这当然很重要。
{1,2}
(基本上是调用构造函数,对吧?)和
std::make_pair(1,2)
之间有什么区别?不,我错了,
{1,2}
。根据[temp.Decrete.call]/1,它是一个非推断上下文。@ThirtyThree四十
{1,2}
调用什么的构造函数?这就是问题所在,这就是为什么它不起作用。编译器无法转发
{1,2}
,直到最后确定要构造的类型。@DyP我认为这就是为什么无法转发它的原因,因为
初始值设定项\u list
@thirty340 make\u pair创建了一对,而myMap::value\u type是一对,因此,它将需要额外的转换来复制元素,然后才能将其存储在映射中。可能对ints不重要;对于更昂贵的型号来说,这当然很重要。
myMap.insert(decltype(myMap)::value_type(1,2));