【问题标题】:Why does reverse_iterator have a default constructor?为什么 reverse_iterator 有默认构造函数?
【发布时间】:2017-09-17 16:03:41
【问题描述】:

我刚刚学习 STL,reverse_iterator 让我很困惑。它有一个默认构造函数,但我不明白如何使用它。 我试过了:

reverse_iterator<int*> r{};
r --;

然后程序崩溃了。我认为这种用法没有意义,很容易导致崩溃,那为什么允许使用默认构造函数呢?

【问题讨论】:

  • 可能只是为了支持声明“未初始化”迭代器稍后分配特定值。只需将默认构造的迭代器视为未初始化的变量,即在分配有意义的值之前不要对它们做任何事情。
  • 为什么允许定义一个指向nullptr 的指针然后取消引用它?有很多被允许的东西是非常不安全的,甚至是未定义的。正是它赋予了 C++ 速度和自爆状态。
  • @RickAstley 我相信 C++ 标准库已经从“随意拍脚”的心态转变为“如果不花钱,你就不会拍脚”。如果允许不安全的事情发生,就必须有更多的理由

标签: c++ stl


【解决方案1】:

std::reverse_iteratorbidirectional iterators,它们有一个明确的要求,即它们是可默认构造的。

至于why bidirectional iterators are default-constructible,主要是因为几乎可以肯定它们实现起来很简单,并且提供这样的保证使算法更容易实现。

int* p = nullptr; *p;之类的东西本身就是UB,它违反了p可解引用的前提条件,让适配器“采用”这种行为是很自然的。

【讨论】:

    【解决方案2】:

    cppreference 上的文档说:

    1) 默认构造函数。 current 是值初始化的。当且仅当值初始化的迭代器上的相应操作也具有定义的行为时,对结果迭代器的操作具有定义的行为。

    有些迭代器对于默认构造是有意义的;通常不是那些与容器直接相关的(我知道的)。例如 istream 迭代器:http://en.cppreference.com/w/cpp/iterator/istream_iterator/istream_iterator。但是,它不是双向的,因此您无法反转它。

    但是,原则上,您可以拥有一个双向的迭代器,并且其默认构造函数/值初始化器至少定义了一些操作。对于这样的迭代器,您希望通过 reverse_iterator 反映行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      相关资源
      最近更新 更多