Linux 我怎么知道 std::map 插入是成功还是失败?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5106170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:00:17  来源:igfitidea点击:

How do I know if std::map insert succeeded or failed?

c++linuxgccstl

提问by Matt

I have a map in a multithreaded app mapping a class called uuid to pointer. What I want to know if an insert operation succeeded for failed.

我在多线程应用程序中有一个映射,将名为 uuid 的类映射到指针。我想知道插入操作是否成功失败。

e.g.

例如

_mymap.insert(hint, MyMap::value_type(entry.uuid, itemptr));

Does it throw an exception or something if it fails?

如果失败,它会抛出异常还是什么?

采纳答案by Armen Tsirunyan

In fact the insert method which takes a hint parameter does not return whether the insert succeeded or not. One way to check if insert actually happened would be to check the size of the map before and after insertion. If it is the same, then insert has failed (i.e. the key was already present). I know it sounds ugly, but that's the most efficient way I could come up with. In fact I believe that there is no compelling reason that the insert with a hint should not return a pair (including the bool) just like the regular non-hint insert does. But once it has been specified in an older standard, it is very hard to change, since it is a breaking change, which the C++ community mostly resents.

实际上,带有提示参数的插入方法不会返回插入是否成功。检查插入是否真的发生的一种方法是检查插入前后地图的大小。如果相同,则插入失败(即密钥已经存在)。我知道这听起来很难看,但这是我能想到的最有效的方法。事实上,我认为没有令人信服的理由表明带有提示的插入不应该像常规的非提示插入那样返回一对(包括 bool)。但是一旦它在旧标准中被指定,就很难改变,因为它是一个破坏性的改变,C++ 社区大多对此表示不满。

Original (wrong) answer

原始(错误)答案

See this link

看这个链接

... returns a pair, with its member pair::firstset to an iterator pointing to either the newly inserted element or to the element that already had its same value in the map. The pair::secondelement in the pair is set to true if a new element was inserted or false if an element with the same value existed.

... 返回一个pair,其成员pair::first设置为一个迭代器,指向新插入的元素或映射中已经具有相同值的元素。pair::second如果插入了新元素,则配对中的元素设置为 true,如果存在具有相同值的元素,则设置为 false。

The link also contains an example

该链接还包含一个示例

For example:

例如:

if(mp.insert(make_pair(key, value)).second == false)
{
   cout << "Insertion failed. Key was present"
}

回答by renanleandrof

The first insert member function returns a pair whose bool component returns true if an insertion was made and false if the map already contained an element whose key had an equivalent value in the ordering, and whose iterator component returns the address where a new element was inserted or where the element was already located.

To access the iterator component of a pair pr returned by this member function, use pr.first, and to dereference it, use *(pr.first). To access the bool component of a pair pr returned by this member function, use pr.second.

The second insert member function, the hint version, returns an iterator that points to the position where the new element was inserted into the map.

第一个插入成员函数返回一对,如果插入,则其 bool 组件返回 true,如果映射已包含其键在排序中具有等效值的元素,则其返回 false,并且其迭代器组件返回插入新元素的地址或者元素已经位于的位置。

要访问此成员函数返回的一对 pr 的迭代器组件,请使用 pr.first,并使用 *(pr.first) 取消引用它。要访问此成员函数返回的一对 pr 的 bool 组件,请使用 pr.second。

第二个插入成员函数,提示版本,返回一个迭代器,指向新元素插入到映射中的位置。

Source: http://msdn.microsoft.com/en-us/library/81ac0zkz(v=vs.80).aspx

来源:http: //msdn.microsoft.com/en-us/library/81ac0zkz(v=vs.80).aspx

回答by 0xC0000022L

Yes, it would throw one of the exceptions used in the STL, e.g. when out of memory. That is in case of failure.

是的,它会抛出 STL 中使用的异常之一,例如,当内存不足时。那是在失败的情况下。

Or were you also interested in knowing whether the element was already contained in the instance?

或者您是否也想知道该元素是否已包含在实例中?

回答by Tristram Gr?bener

typedef std::map<std::string, int> map;
map m;
std::pair<map::iterator,bool> result = m.insert(std::make_pair("hi", 42));

result.second contains what you want

result.second 包含你想要的

回答by FredV

It depends what you mean by failed or succeeded.

这取决于您所说的失败或成功是什么意思。

std::map::insert succeeds when it inserts the new element or returns an iterator to an already existing element.

std::map::insert 在插入新元素或将迭代器返回到已存在的元素时成功。

std::map::insert fails if there is not enough memory to insert a new element and throws std::bad_alloc.

如果没有足够的内存来插入新元素并抛出 std::bad_alloc,则 std::map::insert 失败。

回答by Saint-Martin

It is also possible to know if a pair was inserted or found in a map after insertion with hint (much faster).

还可以知道在使用提示插入后是否在映射中插入或找到了一对(快得多)。

Insert with hint method another pair of the same first, and of a second that you are sure is not in the map ( like (size_t) -1 for a map of sizes for instance ?). If the iterator returned has this impossible value, it has been newly inserted, if not it was found in the map. The iterator returned may then be changed. Example : to insert pairs p (2,4) and p (6, 5) in the map m ((0, 1), (2, 3), (4, 5)).

使用提示方法插入另一对相同的第一对,第二对您确定不在地图中(例如 (size_t) -1 表示大小的地图,例如?)。如果返回的迭代器具有这个不可能的值,则它已被新插入,如果没有在映射中找到。然后可以更改返回的迭代器。示例:在映射 m ((0, 1), (2, 3), (4, 5)) 中插入对 p (2,4) 和 p (6, 5)。

int main (int argc, char* argv []) {
  std::pair<size_t, size_t> tmp [3] = {
    std::pair<size_t, size_t> (0, 1),
    std::pair<size_t, size_t> (2, 3),
    std::pair<size_t, size_t> (4, 5)
  };
  std::map<size_t, size_t> m ((std::pair<size_t, size_t>*) tmp, (std::pair<size_t, size_t>*) &tmp [3]);

  std::cout << "initial map == ";
  std::for_each (m.begin (), m.end (), [] (const std::pair<size_t, size_t>& p) {
    std::cout << p.first << "->" << p.second << "   ";
  });
  std::cout << std::endl;
  std::cout << std::endl;

  {
    //insertion of a pair of first already in map
    std::cout << "insertion of pair 1 == std::pair<size_t, size_t> (2, 4) from second iterator" << std::endl;
    std::map<size_t, size_t>::iterator ihint (m.begin ()), k (ihint); ++ihint;
    std::pair<size_t, size_t> pfoo (2, (size_t) -1);
    k = m.insert (ihint, pfoo);
    if (k->second == (size_t) -1) {
      std::cout << "\tthe pair was inserted" << std::endl;
      k->second = 4;
    }
    else {
      std::cout << "\ta pair with such a first was in the map" << std::endl;
    }
  }
  std::cout << "m after insertion of pair 1 == ";
  std::for_each (m.begin (), m.end (), [] (const std::pair<size_t, size_t>& p) {
    std::cout << p.first << "->" << p.second << "   ";
  });
  std::cout << std::endl;
  std::cout << std::endl;

  {
    //insertion of a pair of first not in map
    std::cout << "insertion of pair 2 == std::pair<size_t, size_t> (6, 5) from third iterator" << std::endl;
    std::map<size_t, size_t>::iterator ihint (m.begin ()), k (ihint); ++ihint; ++ihint;
    std::pair<size_t, size_t> pfoo (6, (size_t) -1);
    k = m.insert (ihint, pfoo);
    if (k->second == (size_t) -1) {
      std::cout << "\tthe pair was inserted" << std::endl;
      k->second = 5;
    }
    else {
      std::cout << "\ta pair with such a first in the map" << std::endl;
    }
  }
  std::cout << "m after insertion of pair 2 == ";
  std::for_each (m.begin (), m.end (), [] (const std::pair<size_t, size_t>& p) {
    std::cout << p.first << "->" << p.second << "   ";
  });
  std::cout << std::endl;
}

outputs : initial map == 0->1 2->3 4->5

输出:初始映射 == 0->1 2->3 4->5

insertion of pair 1 == std::pair (2, 4) from second iterator

从第二个迭代器插入对 1 == std::pair (2, 4)

a pair with such a first was in the map

地图上有一对这样的第一个

m after insertion of pair 1 == 0->1 2->3 4->5

插入对 1 == 0->1 2->3 4->5 后的 m

insertion of pair 2 == std::pair (6, 5) from third iterator

从第三个迭代器插入对 2 == std::pair (6, 5)

the pair was inserted

这对被插入

m after insertion of pair 2 == 0->1 2->3 4->5 6->5

插入对 2 后的 m == 0->1 2->3 4->5 6->5