为什么STD :: SET不提供TRY_EMPLECE成员函数?

发布于 2025-01-20 16:50:00 字数 1083 浏览 5 评论 0原文

std::map(和 std::unordered_map)的 try_emplace 成员函数的一个优点是,如果地图中已存在密钥。我想知道为什么这个成员函数没有添加到 std::set(和 std::unordered_set)接口中,同样的优点也可能适用。

此现场演示显示 std::set::emplace 每次都会分配: https:/ /godbolt.org/z/MjMjPcc89(使用 libstdc++)。

此基准测试表明,当存在重复键时,find + emplace 可能比单独使用 emplace 更快:https://quick-bench.com/q/2IWzv_SJFJpklGjwIKk6wgKsuz0

但是,find + emplace 需要双重查找,以防容器中不存在该键。以下是 std::map 的基准,其中 try_emplace 是最快的选项:https://quick-bench.com/q/ymn1qaxAtrf6FTzHC98e_wkHVZ4

编辑

使用std::set::insert时似乎不会出现分配问题。可惜我之前没试过。

现场演示:https://godbolt.org/z/EjWjfjnsc

One advantage of try_emplace member function of std::map (and std::unordered_map) is that it does not allocate a new node if the key already exists in the map. I wonder why this member function has not been added to the std::set (and std::unordered_set) interface, where the same advantage might apply as well.

This live demo shows that std::set::emplace allocates each time: https://godbolt.org/z/MjMjPcc89 (with libstdc++).

And this benchmark shows that find + emplace may be faster than emplace alone when there are duplicated keys: https://quick-bench.com/q/2IWzv_SJFJpklGjwIKk6wgKsuz0.

However, find + emplace requires a double lookup in case the key is not present in the container. Here is the benchmark for std::map, where try_emplace is the fastest option: https://quick-bench.com/q/ymn1qaxAtrf6FTzHC98e_wkHVZ4.

EDIT

It seems the problem with allocations does not occur when std::set::insert is used. My bad I haven't tried it before.

Live demo: https://godbolt.org/z/EjWjfjnsc

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我的鱼塘能养鲲 2025-01-27 16:50:01

std :: set :: set :: emplace ://en.cppreference.com/w/cpp/container/unordered_set/emplace“ rel =“ nofollow noreferrer”> std :: unordered_set :: emplace 已经等同于try> try_emplace

如果没有键在容器中没有元素的情况下,则将新元素插入与给定args构造的容器中。

但是,请注意:

即使已经有一个元素的元素,该元素也可以是构造的,在这种情况下,新构造的元素将立即被破坏。

std::set::emplace and std::unordered_set::emplace are already equivalent to try_emplace:

Inserts a new element into the container constructed in-place with the given args if there is no element with the key in the container.

However, be aware that:

The element may be constructed even if there already is an element with the key in the container, in which case the newly constructed element will be destroyed immediately.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文