为什么 std::迭代器被弃用?
Why is std::iterator deprecated?
模板类std::iterator
设置为在 C++17 中弃用。 为什么会这样? 这是确保std::iterator_traits
正常工作的便捷方法,尤其是在您可以使用默认模板参数的情况下。 在 C++17 中还有其他方法吗?
从建议弃用它的提案中:
作为编写迭代器类的辅助工具,原始标准库提供了迭代器类模板,以自动声明每个迭代iterator_traits器预期的五个类型定义。然后,这在库本身中使用,例如在
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_function
和binary_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(这也不太难,为了清楚起见,我实际上更喜欢它)。
正如 Barry 所说,工作组已经决定,显式声明类中的类型比从std::iterator
继承更具可读性,并且导致更少的意外。
不过,转换为显式类型并不难(下面的示例取自此处 www.fluentcpp.com)。给定一个声明如下的类:
class MyIterator
: public std::iterator<std::forward_iterator_tag, int, int, int*, int&>
{
...
没有std::iterator
的类变为:
class MyIterator
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = int;
using difference_type = int;
using pointer = int*;
using reference = int&;
// ...
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 如何在c++迭代器类型中包装std::chrono
- std::vector::迭代器是否可以合法地作为指针
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?
- 如何在创建自定义迭代器时获得 std::p air 的第一个和第二个?
- 修改 std::vector 会使迭代器无效吗?
- std::list 中的迭代器感知对象
- 迭代器库中的 std::size() 不适用于传递给函数的 C 样式数组
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 为什么范围算法与 std 的迭代器不兼容?
- 从 std::vector 迭代器中执行函数指针
- 无法获得等效的 std::less 来用于嵌套迭代器
- 再次获得 std::map 会更改之前的迭代器
- 为什么"std::uninitialized_copy"通常取消对未初始化内存的迭代器的引用不是未定
- 创建可以遍历 std::map 值的通用模板迭代器的最简单方法是什么?
- 矢量迭代器不能与 std::shared_ptr<> 取消引用
- 比较未引用的映射迭代器(std::pairs):C2678
- STL迭代器std::distance()错误
- ->秒是否为迭代器 std::map::end()?