我如何将一个空的向量嵌入到 std::map
中?例如,如果我有一个 std::map<int, std::vector<int>>
,并且我想要 map[4]
包含一个空的 std::vector<int>
,我该调用什么函数?
operator[](const Key&)
,当您访问一个不存在的元素时,地图将自动插入一个值初始化的(即在std::vector
的情况下,默认构造的)值。请参见此处:http://en.cppreference.com/w/cpp/container/map/operator_at
(自C++ 11以来,细节有点更复杂,但在您的情况下,这是要紧的)。map[4]
,它将立即给您一个对空(默认构造)向量的引用。分配一个空的向量是不必要的,尽管它可能会使您的意图更加明确。不幸的是,严格正确的答案确实是使用std::piecewise_construct
作为第一个参数,其后跟随两个元组。第一个元组表示创建键(4)的参数,第二个元组表示创建向量(空参数集)的参数。
代码如下:
map.emplace(std::piecewise_construct, // signal piecewise construction
std::make_tuple(4), // key constructed from int(4)
std::make_tuple()); // value is default constructed
map.emplace(4, std::vector<int>());
map[4] = {};
clear
函数即可。std::map<int, std::vector<int>> my_map;
my_map[4].clear();
std::map
的索引运算符,如果指定的索引位置不存在,则会构造一个空值。如果是这种情况,则调用clear
是多余的。但是,如果已经存在一个std::vector<int>
,则调用clear
将清除该向量,导致向量为空。
这可能比我以前的方法更有效,我的以前的方法是赋值给{}
(见下文),因为我们可能计划在位置4添加元素,这样我们就不需要支付任何新分配的成本。此外,如果以前使用my_map[4]
表示未来使用,则我们的新向量很可能最终被调整为几乎与以前相同的大小,这意味着我们节省了重新分配的成本。
只需将其分配给{}
,容器就应该在那里正确构造一个空向量:
std::map<int, std::vector<int>> my_map;
my_map[4] = {};
std::cout << my_map.size() << std::endl; // prints 1
编辑:正如Jodocus所提到的,如果您知道std::map
在位置4上没有包含vector
,那么尝试访问该位置的向量将默认构造一个,例如:
std::map<int, std::vector<int>> my_map;
my_map[4]; // default-constructs a vector there
my_map[4].clear();
而不是赋值。 - Jarod42最简单的解决方案有什么问题吗?std::map[4] = {};
。
在现代C++中,这应该可以做到你想要的,而且开销很小或者没有开销。
如果你必须使用emplace
,我能想到的最好的解决方案是这样的:
std::map<int, std::vector<int>> map;
map.emplace(4, std::vector<int>());
map[4];
,不需要赋值。 - Slava使用 std::make_tuple 和 piecewise_construct:
map.emplace(std::piecewise_construct, std::make_tuple(4), std::make_tuple());
map.emplace(std::piecewise_construct, std::make_tuple(4), std::make_tuple(100, 10));
piecewise_construct
: 这个常量值被传递为构造一个pair对象的第一个参数,以选择构造函数的形式,通过转发两个元组对象的元素到各自的构造函数,就可以就地构造其成员。
std::make_tuple
改为std :: make_tuple()
,那么你的代码实际上会解决OP所问的问题。 - AndyG
map[4]
首先存在吗? - NathanOliver