【问题标题】:std::map and std::set does not return bool with a hintstd::map 和 std::set 不返回带有提示的 bool
【发布时间】:2014-03-20 17:52:37
【问题描述】:

我怎样才能有效地实现这个显然不存在(为什么?)的功能:

std::pair<iterator,bool> std::set::insert (const_iterator hint, const value_type& val);

我想有效地插入一个值(带有提示),同时有一个布尔值告诉我它是否已插入(这是必不可少的)。

为什么没有这样的功能。我想不出一个有效地做到这一点的可能性吗?

非常感谢!

【问题讨论】:

  • 高效定义...为什么需要确定?这是一个多线程问题,其中集合是共享资源并且可以用锁来解决?通常,如果集合已分配,则将在集合中插入元素,除非您要复制大量元素并在此过程中破坏内存。
  • @Claudiordgz 据推测,他的意思是获得与另一个采用插入提示的set|map::insert 重载相同的摊销恒定时间插入性能。多线程与此有什么关系?至于你最后一句话,我不知道你在说什么!
  • 我现在明白了。谢谢你。但是当您插入 set 时,它会将迭代器返回到您插入的位置。 @Gabriel 这似乎是添加到std::set 的好提议。同时,您可以对要插入集合中的元素进行二进制搜索,如果存在则不要插入。如果是,请检查迭代器的有效位置。请记住,插入无效位置会被传递,您可能会遇到问题。
  • 我的意思正是 Praetorian 指出的 :-)!

标签: c++ c++11 stl stdmap stdset


【解决方案1】:

通常假设如果你有一个提示迭代器是通过findequal_rangelower_boundupper_bound 获取的,或者正在插入一个排序序列,所以如果你需要知道你可以检查*hint(或者可能是*prev(hint))是否等同于val你自己:

iterator hint = s.lower_bound(val);
// (hint == s.end() || !(*hint < val)) && (hint == s.begin() || *prev(hint) < val)
if (hint != s.end() && !(val < *hint))
    ; // equivalent
else
    s.insert(hint, val); // guaranteed to insert

请注意,如果插入失败(即*hint 等同于val),插入带提示保证在 O(1) 中执行,因此您应该检查无论如何,在调用insert 之前插入都会成功。

同样,对于从upper_bound 派生的提示迭代器:

iterator hint = s.upper_bound(val);
// (hint == s.end() || val < *hint) && (hint == s.begin() || !(val < *prev(hint)))
if (hint != s.begin() && !(*prev(hint) < val))
    ; // val is equivalent to *prev(hint)
else
    s.insert(hint, val); // guaranteed to insert

【讨论】:

  • assert(!(*hint &lt; val))
  • @Gabriel 它只是记录lower_bound 的行为;我会把它变成评论。
  • 啊,好吧,现在我明白了 :-),但如果有人从这样的函数中获取提示,这是一种解决方案,如果有人有其他由自己派生的提示,则无法绕过我认为std::set 的新 stl 重载...?
  • @Gabriel 这取决于您如何派生提示迭代器;如果您希望使用提示,那么它必须是 lower_boundupper_bound 位置。
  • 在 C++11 中,它总是尝试在提示之前插入。
猜你喜欢
  • 2017-07-28
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多