为什么不推荐使用std :: iterator?

时间:2017-04-07 01:16:47

标签: c++ c++17

模板类std::iterator设置为在C ++ 17中弃用。为什么这样?它是确保std::iterator_traits有效的一种方便方法,特别是如果您可以使用默认模板参数。在C ++ 17中还有其他一些方法吗?

1 个答案:

答案 0 :(得分:25)

来自the proposal that suggested its deprecation

  

作为编写迭代器类的辅助工具,原始标准库提供了迭代器类模板,以通过iterator_traits自动声明每个迭代器所需的五个typedef。然后将其用于库本身,例如在std::ostream_iterator

的规范中
template <class T, class charT = char, class traits = char_traits<charT> >
class ostream_iterator:
  public iterator<output_iterator_tag, void, void, void, void>;
     

对于读者而言,void参数的长序列不仅仅是简单地在类定义本身中提供预期的typedef,这是当前工作草案采用的方法,遵循C +中设置的模式+14我们在unary_functionbinary_function的所有仿函数库中弃用了派生。

     

除了降低清晰度之外,迭代器模板还为不谨慎的人设置了一个陷阱,因为在典型的用法中它将是一个依赖的基类,这意味着它不会在从类中查找名称或其中查找成员职能。这导致惊讶的用户试图理解为什么以下简单用法不起作用:

#include <iterator>

template <typename T>
struct MyIterator : std::iterator<std::random_access_iterator_tag, T> {
   value_type data;  // Error: value_type is not found by name lookup 

   // ... implementations details elided ...
};
     

仅仅清晰的原因足以说服LWG更新标准库规范,不再强制标准迭代器适配器派生自std::iterator,因此标准本身不再使用此模板。因此,它似乎是一个强烈的弃用候选人。

您还可以在LWG 2438中看到STL的推理。 (h / t T.C.

至于其他一些做法,不是真的。您基本上可以实现自己的std::iterator版本(这不是太难)或手动写出所有这些typedef(这也不是太难,为了清晰起见,我实际上更喜欢它)。