Enr*_*lis 3 c++ iterator stl language-lawyer reverse-iterator
+-- v.begin() +-- v.end()\n | |\n v v\n +---+---+---+---+---+---+ - +\n | o | o | o | o | o | o | x |\n +---+---+---+---+---+---+ - +\n\n+ - +---+---+---+---+---+---+\n| x | o | o | o | o | o | o |\n+ - +---+---+---+---+---+---+\n ^ ^\n | |\n +-- v.rend() +-- v.rbegin()\nRun Code Online (Sandbox Code Playgroud)\n(从这个答案中复制并编辑了 ASCII ,这实际上促使我提出当前的问题。)
\n我确实看到了这样做的好处&*rit == &*(rit.base() - 1),因为这样我就可以rit.base()对任何反向迭代器采用rit,并且我总是会得到一个有效的迭代器。
但同时
\nv.rbegin().base();我必须记住先减1 *(v.rbegin().base() - 1),,v.rend().base() - 1完全取消引用,因为我不能取消引用v.rend() 。如果设计是这样呢&*rit == &*rit.base()?
v.rend().base()无法取消引用;v.rend().base() - 1v.end()直接从反向迭代器获取,甚至是最接近的迭代器,b.rbegin()但这只是对应于- 1我们必须在当前设计中添加的rit.base(),以获得与反向相同元素的正向迭代器。我的意思是,在我看来,无论设计决策是那样&*rit == &*(rit.base() - 1)还是那样&*rit == &*rit.base(),我们都会获得相同的便利
rit.base()实际设计中总是没问题的,- 1在替代设计中通常不需要和不便
\nrit.base()在实际设计中取消引用所有有效的 s,+1 v.rbegin()进入v.end()替代设计,只是在相反的情况下。
\n所以我的问题是:做出确实做出的选择是否有明确的优势?或者这只是一枚抛硬币?
\n我发现第一个元素之前没有有效的迭代器,但这就是我的观点。std::prev(v.begin())当引入反向迭代器时,制作一个像这样的有效的、不可解引用的迭代器会有什么问题v.end()?
事后看来,我确实看到了一个不容置疑的优势。
\n我没有看到v.rbegin().base() == v.end()/的优点v.rend().base() == v.begin(),因为为什么我想从它们的反向对应项创建v.end()/ v.begin()?
但是,如果我有两个反向迭代器rit1并且rit2定义了 range (rit1, rit2],那么采用it1 = rit1.base()和it2 = rit2.base()可以轻松引用相反方向的相同范围的元素,[it1, it2)。
长话短说:_我应该阅读《C++ 标准库 - 第二版》中的 \xc2\xa79.4.1。第一的。
\n这不是一个设计决定,而是一个必然。
反向迭代器并不是一个神奇的东西,它能够以某种方式反向迭代一个范围。它是一个建立在已有事物之上的立面。
当您有一个包含 6 个条目的集合(如您的图片所示)时,您所拥有的只是 7 个可用迭代器值,仅此而已(6 个是可取消引用的,一个是最终迭代器值)。这就是反向迭代器可以构建的全部内容。
由于没有开始前的迭代器(就像第二张图片让人想到的那样),因此反向迭代器除了映射到rbegin()和end()到rend()之外没有其他选择begin()。也就是说,你有(rbegin() + i).base() == end() - i
反过来,这又要求可解除引用的迭代器(从 开始的前 6 个迭代器rbegin())实际上必须解除引用 iterator .base()-1。没有其他方法可以实现反向迭代器。
| 归档时间: |
|
| 查看次数: |
427 次 |
| 最近记录: |