c++ - std::map、std::set 和 std::priority_queue 中的比较器

标签 c++ c++11 c++14 move-semantics functor

所有这三个容器都通过 const 引用接受函数对象,而不是值或转发引用。这导致需要将函数对象复制到容器的内部存储中(最多两次)。

复制函数对象两次有什么原因吗?与让用户能够传递任何类型的函数对象并将其构造到内部仿函数存储中相反?这样库就更通用了,用户的惊喜也更少了。


push_back() 函数中应用了相同的原理 - 它们有两个重载,一个带有 const 引用,一个带有右值引用,因为这让用户可以更好地控制他们是否想要 move 值或复制值。该库在一般情况下保持高效,无需对用例做出任何假设。

我怀疑这是一个从前 C++11 时代开始就沿用下来的设计决策。更改此标准是否是一个不错的建议?

最佳答案

通常,比较器是一个非常小的对象,复制起来很便宜,而且您只需构建一次容器。一次多一份拷贝并不重要。真的。您可能不会在对延迟敏感的代码中创建一堆 std::map。因此,为这些容器引入更多构造函数并没有太多好处。这样的提议会是什么样子?那么您是否也想通过右值引用获取 Allocator?现在我们要添加更多的构造函数。将所有采用 Compare const& 的构造函数更改为采用受约束的转发引用?现在,我们打破 ABI 以获得仍然微不足道的 yield (如果有的话)。构造函数很复杂。我什至不相信如果今天设计 std::map,界面在这方面看起来会有所不同。如果有的话,我们可能只是按值而不是按 const& 来获取 Compare

另一方面,push_back 在程序的主要运行期间被大量使用,具有多种类型。能够 move 到 vector 中,或者 emplacevector 中,是一个巨大的胜利。这两种情况真的没有可比性。

关于c++ - std::map、std::set 和 std::priority_queue 中的比较器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42662750/

相关文章:

c++ - 如果存储在中间 "double"变量中,浮点计算会发生变化

c++ - 可变参数模板函数中对重载函数的不明确调用

c++ - 获取 std::map 中的最小键

c++ - 尝试使用 Redispp 在类中设置全局 Redis 连接

c++ - 避免并发等待对象中的死锁

java - 不同风格的程序流程?

c++ - C++中的隐式类型转换字母

c++ - 为什么我们在 C++ 中使用返回数据结构的函数?

c++ - asio::thread_pool 在调用构造函数之前就失败了

c++ - 用双花括号初始化 vector :std::string vs int