将元素插入 std::unorder_set 时,是否值得在 std::unordered_set::insert 之前调用 std::unordered_set::find?根据我的理解,我应该总是调用 insert 因为它返回一个 std::pair ,其中包含一个告诉插入是否成功的布尔值。
3 回答
find
之前调用insert
本质上是一种反模式,通常在设计不佳的自定义集实现中观察到。也就是说,在不告诉调用者插入是否实际发生的实现中可能是必要的。std::set
确实为您提供了这些信息,这意味着通常不需要执行这种先查找后插入的舞蹈。
的典型实现insert
通常包含 的完整实现find
,这意味着find-before-insert方法会毫无意义地执行两次搜索。
然而,std::set
设计的其他一些缺点有时确实需要先查找后插入序列。例如,如果您的 set 元素包含一些需要修改的字段,如果(仅当)实际插入发生。例如,您可能必须为某些指针字段分配“永久”内存,而不是这些字段在插入之前指向的“临时”(本地)内存。不幸的是,这在插入之后是不可能的,因为std::set
只为您提供了对其元素的非修改访问。一种解决方法是先做一个find
,从而“预测”是否会发生实际插入,然后相应地设置新元素(如分配“永久”做insert
. 从性能的角度来看,这很丑陋,但在非性能关键代码中是可以接受的。这就是标准容器的情况。
最好只尝试插入,否则散列和迭代散列桶中碰撞的任何元素的工作是不必要的重复。
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.