无序集,在插入之前值得调用find吗?

时间:2014-04-11 02:17:59

标签: c++ unordered-set

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

3 个答案:

答案 0 :(得分:2)

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

insert的典型实现通常包含find的完整实现,这意味着 find-before-insert 方法执行搜索两次没有任何意义。

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

答案 1 :(得分:1)

最好只尝试插入,否则将不必要地重复散列和迭代在散列桶中发生冲突的任何元素的工作。

答案 2 :(得分:1)

如果你设置了线程安全并同时访问,那么首先调用find几乎没有,因为insert将是原子的,但是check-then-act将容易受到竞争条件的影响。

因此,一般而言,尤其是在多线程上下文中,只需插入。