emplace_back
将所有参数转发到成员类型的匹配构造函数中。现在,
std::map
具有初始化列表构造函数,但它需要一个
std::pair<const Key, Value>
的列表,即
std::pair<const int, int>
。由于
push_back
不是一个模板,因此它只期望一个类型,并在原地执行转换。也就是说,这里没有进行任何类型推导。
您需要明确声明要使用
std::pair
;以下代码应该有效:
#include<map>
#include<vector>
int main()
{
std::vector<std::map<int, int>> v;
v.emplace_back(std::initializer_list<std::pair<const int, int>>{
{1,2},{3,4},{5,6}});
return 0;
}
出于同样的原因,这段代码无法编译:
v.emplace_back({std::pair<const int,int>(1,2),
std::pair<const int,int>(3,4)});
这是因为,虽然括号括起来的列表可以产生初始化列表,但并不一定如此。它也可以是构造函数调用或类似的内容。因此,写成:
auto l = {std::pair<const int,int>(1,2),
std::pair<const int,int>(3,4)}
产生l
的初始化列表,但表达式本身可能以其他方式使用:
std::pair<std::pair<const int, int>, std::pair<const int, int>> p =
{std::pair<const int,int>(1,2),
std::pair<const int,int>(3,4)}
这整个东西有些混乱。
基本上,如果你有一个括号括起来的列表,它可能生成一个初始化列表或调用匹配的构造函数。有些情况下编译器无法确定需要哪些类型;emplace_back
就是其中之一(因为需要转发)。在其他情况下,它可以工作,因为所有类型都在表达式中定义了。例如:
#include <vector>
#include <utility>
int main()
{
std::vector<std::pair<const int, int>> v =
{{1,2},{3,4},{5,6}};
return 0;
}
现在它无法工作的原因是无法推导出任何类型。也就是说,emplace_back
试图推断输入类型的名称,但这是不可能的,因为大括号括起来的列表可以描述多种类型。因此,没有匹配的函数调用。
v.emplace_back( std::map<int, int>{{1,2}} );
.. 当然不是理想的。 - M.M