什么是"提示"?

时间:2014-10-28 23:30:35

标签: c++ c++11

cppreference关于map::emplace_hint()

template <class... Args>
iterator emplace_hint( const_iterator hint, Args&&... args );
     

使用hint作为元素应该去的建议,将新元素插入到容器中。

因此,如果这是一个建议,那是否意味着实现没有将元素放在那里?究竟是什么提示?

3 个答案:

答案 0 :(得分:9)

cppreferencemap::emplace_hint()的准确性不准确。但是,应该可以原谅这一点,因为在C ++ 11之前的某个时刻,草案明确授予了实现忽略提示的权限:

来自N3225,表102:

  

...允许实现忽略提示。

幸运的是,这已由LWG 1253和C ++ 11及前向读取更正:

  

...元素尽可能靠近p之前的位置插入。

     

一般情况下是对数,但如果在p

之前插入元素,则摊销常数

所以“提示”现在有了牙齿。 必须得到尊重。虽然请注意,这些注释仅适用于关联容器(map,multimap,set,multiset)。

在C ++ 98/03中,“提示”未正确用于insert。但N1780更正了这一点,随后emplace_hint采用了这一措辞。

继续允许实现忽略无序容器的提示。这是有充分理由的。没有良好的实施策略来利用无序容器的提示。提示只是为了提供与容器通用代码中的关联容器的兼容性。

答案 1 :(得分:8)

通常,插入基于树的映射(如std::map)需要进行O(log n)查找才能找到正确的插入点。如果正确的插入点与您提供的提示相邻,则可以保存O(log n)查找,而操作为O(1)。

通常的用例是在没有给定密钥的现有项目时插入项目。然后,不是使用.find()(如果找不到该项,则返回.end()),而是使用.lower_bound()来查找现有键(如果是,则返回插入点的迭代器)密钥未找到)。然后,如果密钥不存在,则使用该迭代器进行提示插入。

答案 2 :(得分:1)

std::map是一个关联容器,用于保持键值对按排序。由于与查找相关的成本,插入具有O(logN)复杂度。但是通过提供一个提示,迭代器从哪里开始搜索 - 插入可以在分摊的常量时间而不是对数时间内进行。