从std::map中按键弹出一个元素

c++: popping an element by key out of an std::map

本文关键字:一个 元素 map std      更新时间:2023-10-16

我有兴趣从映射中删除具有特定键的元素,并使用该元素。

看起来像:

itr = MyMap.pop(wantedKey);
//Now MyMap is missing the element which has the key 'wantedKey'.
//Do something with this element through 'itr'.

是否有一个stl map方法来做这个?

编辑

carleeto的响应之后,我想澄清一下:我需要的是从map中删除元素,然后程序能够使用它,它可以是元素本身作为一对,不一定是迭代器。

有两种选择:就地使用然后删除它,或者将它移动到一个局部变量,删除条目,然后使用它。

// use-remove
auto i = MyMap.find(wantedKey);
if (i != MyMap.end()) {
    // use-remove
    use(i->second);
    MyMap.erase(i);
    // or
    // move-remove-use
    auto x = std::move(i->second);
    MyMap.erase(i);
    use(x);
} else {
    // Not found
}

我不知道,但是您可以使用std::map::find来获取迭代器,然后在完成后使用该迭代器作为参数调用std::map::erase

从您的变量命名来看,我认为您可能会混淆这里的概念。

itr = MyMap.pop(wantedKey);
//Do something with this element through 'itr'.

迭代器只指向容器中的元素。因此,如果您通过名为pop的函数接收到一个迭代器(即使它存在),迭代器将不会引用您弹出的元素,而可能是在它之后或之前的元素,如std::vector::erase。这是因为迭代器的目的是遍历容器中的元素。因此,如果一个元素不在容器中,就不能获得该元素的迭代器。然而,即使使用erase函数返回的迭代器,它也不会引用您希望它引用的对象。

因此,可以像许多人指出的那样,通过搜索元素,将迭代器指向该元素,然后用该迭代器调用erase函数,从map中删除该元素。但是不能得到指向已删除元素的迭代器。

UPDATE:如果你只想访问和使用元素,那么你所需要做的就是使用std::map::find获取一个迭代器,std::map::erase从映射中删除该元素,当你使用完迭代器后,使用。原因是,即使您已经存储了迭代器的副本以供将来使用,一旦调用erase,它将失效。为了能够在擦除它之后访问它,根据作用域的不同,您可能需要复制它。

最后,您想做的是一个非常常见的任务——根据键查找映射并对相关元素执行操作。很可能你有一个键列表要浏览。您还应该查找函数std::for_each和std::transform。我意识到这不是在你删除它之后对元素进行操作,但我想我会添加它,看看它是如何相关的操作。例如:您可以将所有与键列表匹配的元素移动到另一个容器中(例如,vector容器),然后使用上述方法对它们进行操作。

也许你想做的是

itr = MyMap.find('thing in a string');

查找迭代器并使用它,

MyMap.erase(itr)

然后擦掉

Pop()属于堆栈数据结构。要访问一个映射的元素,使用[]操作符(http://www.cplusplus.com/reference/map/map/operator%5B%5D/),从映射使用(http://www.cplusplus.com/reference/map/map/erase/)中删除它。

itr = MyMap.find(wantedKey);
if(itr != MyMap.end()) {
  use( itr->second );
  MyMap.erase(itr);
}
your.uncle = bob;

使用c++的std::map<T, U>::find():

map.erase(map.find(key));

我的做法如下。在我的例子中,映射存储std::shared_ptr值,使得复制成本较低,并且对象所有权转移清晰。

auto it = MyMap.find( wantedkey );
if ( it == MyMap.end() ) throw runtime_error("not found");
auto ret = it->second;          // make copy of shared_ptr
MyMap.erase(it);
return ret;

调用者获得一个引用计数至少为1的shared_ptr(来自副本)。注意,函数必须按值返回shared_ptr,等等。