无序集,值得在插入之前调用find
unordered set, it it worth calling find before insert?
当将元素插入std::unorder_set时,是否值得在std::unrdered_set::insert之前调用std::uncrdered_sep::find?根据我的理解,我应该总是调用insert,因为它返回一个std::pair,其中包含一个bool,它告诉插入是否成功。
在insert
之前调用find
本质上是一种反模式,这通常在设计不佳的自定义集实现中观察到。也就是说,在不告诉调用者插入是否真的发生的实现中,这可能是必要的。std::set
确实为您提供了这些信息,这意味着在插入舞蹈之前,通常不需要执行此查找。
insert
的典型实现通常包含find
的完整实现,这意味着插入前查找方法无意义地执行两次搜索。
然而,std::set
设计的一些其他缺点有时确实需要在插入序列之前进行查找。例如,如果您的集合元素包含一些字段,则在实际插入发生时(仅当)需要修改这些字段。例如,您可能必须为某些指针字段分配"永久"内存,而不是这些字段在插入之前指向的"临时"(本地)内存。不幸的是,在插入之后不可能执行操作,因为std::set
只为您提供对其元素的非修改访问权限。一种解决方法是先执行find
,从而"预测"是否会发生实际插入,然后在执行insert
之前相应地设置新元素(如为所有字段分配"永久"内存)。从性能的角度来看,这是丑陋的,但在非性能关键代码中是可以接受的。标准容器就是这样。
最好只是尝试插入,否则对哈希桶中发生冲突的任何元素进行哈希和迭代的工作都会不必要地重复。
如果您将其设置为线程安全并同时访问,那么首先调用find
的作用很小,因为insert
是原子的,但随后的检查会受到竞争条件的影响。
因此,一般来说,尤其是在多线程上下文中,只需插入即可。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 使用 std::find 时没有匹配的函数调用错误
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 从基于迭代器的for循环转换后,如何在map::find()中调用方法
- 调用 QSqlTableModel setTable 方法时出现"Unable to find table"错误
- 调用 std::set<Type*>::find 时避免const_cast
- 跟踪节点遍历调用 std::map::find
- 避免使用临时std::string来调用boost::unordereded_map::find
- 在用户定义对象上调用std::find时出错
- 没有匹配的函数调用Std::find
- 无序集,值得在插入之前调用find