【问题标题】:Is the time complexity of `std::vector<T>::clear` *really* not specified?`std::vector<T>::clear` *真的*没有指定时间复杂度吗?
【发布时间】:2012-12-30 20:35:13
【问题描述】:

this question 的处理过程中,发现 C++ 标准似乎对std::vector&lt;T&gt;::clear 没有时间复杂度要求。

23.2.3 下的表 100 说:

销毁a 中的所有元素。使所有引用 a 元素的引用、指针和迭代器无效,并可能使过去的迭代器无效。帖子:a.empty() 返回true

然后……就是这样。在 23.3.6 下没有专门针对它的条目,也没有显式表明以下适用于clear

[C++11: 23.3.6.1/1]: 向量是支持随机访问迭代器的序列容器。此外,它支持(摊销的)恒定时间最后的插入和擦除操作;在中间插入和擦除需要线性时间。存储管理是自动处理的,但可以给出提示以提高效率。 [..]

那么……这是真的吗?还是我只是错过了它?

【问题讨论】:

  • 参见 23.3.6.5/4,仍在寻找 clear 作为 erase(begin(),end()) 获取 sequences...
  • @K-ballo:在哪里强制要求等效?
  • 我说我还在找它:P
  • @K-ballo:哦,这就是你的意思=)是的,我也一直在寻找它......没有成功......
  • @usr:标准库是基于模板的,所以绝对没有理由不能专门针对 POD 元素类型。

标签: c++ std language-lawyer


【解决方案1】:

这似乎是DR 704(以及相关的DR 1301)的意外结果,它删除了clear() 等同于erase(begin(), end()) 的措辞,因为erase() 需要MoveAssignable,擦除时不需要每个元素。删除erase() 方面的定义也删除了复杂性要求。这可能可以在编辑上处理;我已向委员会提出。

注意std::deque::clear()std::forward_list::clear() 也会受到影响。 std::list::clear() 确实有复杂性保证。

编辑:现在是http://cplusplus.github.com/LWG/lwg-active.html#2231

【讨论】:

  • 擦除尾随子集也不需要MoveConstructible。那么resize(0) 呢?或许让clear()等于resize(0)会更好,从而得到resize的复杂度要求。
  • 大多数序列没有resize()。对类型的要求(即必需的概念)不是根据值指定的,而是根据类型指定的。 erase(i, j) 的概念检查需要 MoveAssignable(不是我最初写的 MoveConstructible,抱歉),即使对于特定值 ij 不会发生任何移动。
  • 嗯。然后似乎需要进行另一个操作(也许是truncate),以便从指定的迭代器擦除到最后。通常erase(it, end() 用于此目的,但新操作不需要像erase 那样需要MoveAssignable
  • 对于erase()vectordeque 需要MoveAssignable 的序列容器,已经提供了满足该需求的pop_back()resize()。我不认为当前的问题可以通过添加truncate() 来解决,问题是clear() 被不恰当地定义为erase() 并不是说​​没有办法从最后清除非MoveAssignable 元素的一个序列。问题在于标准中的措辞选择不当,而不是缺少功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 2015-03-01
  • 1970-01-01
相关资源
最近更新 更多