4

将元素插入 std::unorder_set 时,是否值得在 std::unordered_set::insert 之前调用 std::unordered_set::find?根据我的理解,我应该总是调用 insert 因为它返回一个 std::pair ,其中包含一个告诉插入是否成功的布尔值。

4

3 回答 3

2

find之前调用insert本质上是一种反模式,通常在设计不佳的自定义集实现中观察到。也就是说,在不告诉调用者插入是否实际发生的实现中可能是必要的。std::set确实为您提供了这些信息,这意味着通常不需要执行这种先查找后插入的舞蹈。

的典型实现insert通常包含 的完整实现find,这意味着find-before-insert方法会毫无意义地执行两次搜索。

然而,std::set设计的其他一些缺点有时确实需要先查找后插入序列。例如,如果您的 set 元素包含一些需要修改的字段,如果(仅当)实际插入发生。例如,您可能必须为某些指针字段分配“永久”内存,而不是这些字段在插入之前指向的“临时”(本地)内存。不幸的是,这在插入之后是不可能的,因为std::set只为您提供了对其元素的非修改访问。一种解决方法是先做一个find,从而“预测”是否会发生实际插入,然后相应地设置新元素(如分配“永久”insert. 从性能的角度来看,这很丑陋,但在非性能关键代码中是可以接受的。这就是标准容器的情况。

于 2014-04-11T02:41:35.267 回答
1

最好只尝试插入,否则散列和迭代散列桶中碰撞的任何元素的工作是不必要的重复。

于 2014-04-11T02:23:15.340 回答
1

If your set it threadsafe and accessed concurrently then calling find first does very little, as insert would be atomic but a check-then-act would be susceptible to race condition.

So in general and especially in a multithreaded context, just insert.

于 2014-04-11T02:25:45.827 回答