我如何知道 std::map 插入成功还是失败?
我在多线程应用程序中有一个映射,将名为 uuid 的类映射到指针。 我想知道插入操作是否成功或失败。
例如,
_mymap.insert(hint, MyMap::value_type(entry.uuid, itemptr));
如果失败,它会抛出异常或其他异常吗?
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.
e.g.
_mymap.insert(hint, MyMap::value_type(entry.uuid, itemptr));
Does it throw an exception or something if it fails?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
事实上,带有提示参数的插入方法不会返回插入是否成功。检查插入是否实际发生的一种方法是检查插入前后地图的大小。如果相同,则插入失败(即密钥已经存在)。我知道这听起来很丑陋,但这是我能想到的最有效的方法。事实上,我认为没有令人信服的理由表明带有提示的插入不应像常规的非提示插入那样返回一对(包括布尔值)。但是,一旦在较旧的标准中指定了它,就很难更改,因为这是一个重大更改,而 C++ 社区大多对此表示不满。
原始(错误)答案
查看此链接
...返回一对,其中它的成员
pair::first
设置为一个迭代器,该迭代器指向新插入的元素或指向映射中已具有相同值的元素。如果插入了新元素,则对中的pair::second
元素设置为 true;如果存在具有相同值的元素,则设置为 false。该链接还包含一个示例
例如:
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.
Original (wrong) answer
See this link
... returns a pair, with its member
pair::first
set to an iterator pointing to either the newly inserted element or to the element that already had its same value in the map. Thepair::second
element in the pair is set to true if a new element was inserted or false if an element with the same value existed.The link also contains an example
For example:
result.second 包含你想要的内容
result.second contains what you want
这取决于你所说的失败或成功是什么意思。
std::map::insert
当插入新元素时成功,否则返回一个指向已存在元素的迭代器。如果没有足够的内存来插入新元素,
std::map::insert
将失败并抛出std::bad_alloc
。It depends what you mean by failed or succeeded.
std::map::insert
succeeds when it inserts the new element, otherwise it returns an iterator to an already existing element.std::map::insert
fails if there is not enough memory to insert a new element and throwsstd::bad_alloc
.来源:http://msdn.microsoft.com/ en-us/library/81ac0zkz(v=vs.80).aspx
Source: http://msdn.microsoft.com/en-us/library/81ac0zkz(v=vs.80).aspx
是的,它会抛出 STL 中使用的异常之一,例如内存不足时。那是在失败的情况下。
或者您是否也有兴趣了解该元素是否已包含在实例中?
Yes, it would throw one of the exceptions used in the STL, e.g. when out of memory. That is in case of failure.
Or were you also interested in knowing whether the element was already contained in the instance?
如果
insert()
尝试插入但失败,则抛出std::bad_alloc
;如果它选择不插入,因为具有该键的值已经存在,那么它不会抛出。它只是返回一个指向现有元素的迭代器。带有提示的
insert()
版本仅返回一个迭代器,与无提示版本不同,后者还返回值是否已插入或已存在的指示。CPP Reference 建议使用
size()
的变化来确定插入是否成功。我们可以尝试类似的实际上,对于问题中的示例(构造一个键值对),我们可能希望包装
emplace_hint()
成员函数,因此我们可以传递一对或单独的键和值:insert()
throwsstd::bad_alloc
if it tried to insert but failed; if it chose not to insert because a value with that key already exists, then it does not throw. It just returns an iterator to the existing element.The version of
insert()
that takes a hint just returns an iterator, unlike the non-hinted version which also returns an indication of whether the value was inserted or was already present.CPP Reference suggests using change of
size()
to determine whether the insert was successful. We could try something likeActually, for the example in the question (which constructs a key-value pair), we probably want to be wrapping the
emplace_hint()
member function, so we could pass either a pair or separate key and value:比较插入前和插入后地图的大小,以了解插入元素是否很慢(Debian 8中的map::size很慢:浏览完整地图)
可以知道是否在地图中插入或找到了一对使用提示插入后无需重新计算大小,使用提示插入方法。
使用提示方法插入另一对相同的第一个,以及您确定不在映射中的第二个(如 -1 表示正第二个整数的映射)。如果返回的迭代器具有这个不可能的值,则它是新插入的,如果不是,则它是在映射中找到的。然后返回的迭代器可能会被更改。中插入对p (2,4) 和p (6, 5)米 ((0, 1), (2, 3), (4, 5))。
示例:在map
输出:
初始映射 == 0->1 2->3 4->5
插入对 1 == std::pair; (2, 4) 来自第二个迭代器的
后在映射 m 中
一对具有这样的第一个在插入对 1 == 0->1 2->3 4->5
插入对 2 == std:: 对(6, 5) 从第三个迭代器
插入m
开始,该对在插入对 2 == 0->1 2->3 4->5 6->5 之后
Comparing the size of the map before insertion and after insertion to know if an element was inserted is slow (map::size is slow with Debian 8: browsing complete map)
It is possible to know whether a pair was inserted or found in a map after insertion with hint without recalculating size, using hint insertion method.
Insert with hint method another pair of the same first, and of a second that you are sure is not in the map ( like -1 for a map of positive second int). 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<int, int> m ((0, 1), (2, 3), (4, 5)).
outputs :
initial map == 0->1 2->3 4->5
insertion of pair 1 == std::pair<int, int> (2, 4) from second iterator
a pair with such a first was in the map
m after insertion of pair 1 == 0->1 2->3 4->5
insertion of pair 2 == std::pair<int, int> (6, 5) from third iterator
the pair was inserted
m after insertion of pair 2 == 0->1 2->3 4->5 6->5
根据 文档, std::map insert 返回一对两个值:“插入元素(或阻止插入的元素)的迭代器和当且仅当插入发生时设置为 true 的 bool 值。”
根据您用于映射的类型,您可以执行类似于上面建议的 Tristram 的操作,您可以在其中创建结果对。但是,如果您只想要其中一个值(例如,表明插入是否成功的布尔值),则类似这样的事情可能会更简单:
如果您只想要布尔值,则可以这样做
,或者如果您只想要迭代器,则可以这样做 这基本上是
说“嘿,我刚刚从 insert() 中得到了一对,我只关心该对中的一个,所以让我设置一些等于该块的变量”。
但是,请注意,这并不适用于 insert() 的每个版本。有些 insert 的返回值只是迭代器,有些不返回任何内容,甚至返回一个
insert_return_type
,因此请检查文档以了解哪种特定情况与您正在编写的代码相关。According to the documentation, std::map insert returns a pair of two values: "an iterator to the inserted element (or to the element that prevented the insertion) and a bool value set to true if and only if the insertion took place."
Depending on the types you are using for mapping, you can potentially do something like what Tristram suggested above, where you create a result pair. However, if you only want one of the values (e.g. the bool that states whether insertion was successful or not), something like this might be simpler:
If you only want the bool, you can do
or if you only want the iterator, you can do
This basically says "hey, I just got a pair as a result from insert(), I only care about one piece of that pair, so let me set some variable equal to that piece".
However, note that this doesn't work with every version of insert(). Some return values from insert are only the iterator, some return nothing, one even returns an
insert_return_type
, so please check the documentation to see which particular case is relevant to the code you're writing.