哪个更好 std::prev(itr) 或 --itr?

Posted

技术标签:

【中文标题】哪个更好 std::prev(itr) 或 --itr?【英文标题】:Which one is better std::prev(itr) or --itr? 【发布时间】:2018-04-10 14:26:21 【问题描述】:

我正在迭代一个双向数据结构。我可以使用 (++, --) 或 (std::prev,std::next,std::advance) 来实现。以后使用比其他有优势吗?

【问题讨论】:

请更具体一点:容器/迭代器到底是什么? @Sumit Jha 有时它们不可互换。例如比较 auto next = std::next( first );并且自动下一个 = ++first; 主要是它们不等价。但这就是说std::prev 会对自然不允许朝那个方向迭代的容器做坏事,--itr 在这样的容器上不会编译。所以我会使用后者。 @Bathsheba std::prev 不会在底层使用operator--,因此如果迭代器不是双向的,也无法编译? 【参考方案1】:

他们做的事情略有不同。所以总的来说两者都不是更好。

特别是std::prev 不会修改itr。因此,最好在 itr 不应该或不能修改时(参见 S.M. 的答案,例如后者)。 --itrstd::advance 一定要修改 itr,所以在必须修改 itr 时更好。

std::prevstd::advance 优于 --itr 的一个优点是它们的参数 n 在您需要推进多个步骤时可以避免编写循环。如果迭代器是随机访问,它们比循环更有效。

【讨论】:

如果迭代器是随机访问的,我们也可以做i + ni += n... @Aconcagua 和使用std::prev / std::advance 优于- / -= 的(可能是不利的)优势在于它适用于任何类型的双向迭代器;不仅仅是随机访问。 @Aconcagua 我忘了在我最后的评论中添加,确实,使用-- 循环也适用于非随机访问迭代器。 好吧,除了你回答的最后一句话之外,我不同意你的观点......虽然技术上没有错,但使用 RA 迭代器我不会循环,而是使用 +/-(=) n而是运营商。 std::advance 的主要好处是不必使用 NRA 迭代器显式编写循环...“一致性”也可以作为在 RA 迭代器上使用它的参数。 @Aconcagua 我经常希望我的算法与 NRA 迭代器一起使用,但我也希望提高使用 RA 迭代器的效率。 std::prevstd::advance 实现了这两个目标。 +/-(=) 运算符不能同时实现两者。【参考方案2】:

我认为优势在cppreference.com 中得到了很好的描述。例如std::prev 具有如下所述的优势:

虽然表达式--c.end()经常编译,但不能保证 这样做:c.end() 是一个右值表达式,并且没有迭代器 要求保证右值的减少 去工作。特别是,当迭代器被实现为指针时, --c.end() 不能编译,而 std::prev(c.end()) 可以。

【讨论】:

以上是关于哪个更好 std::prev(itr) 或 --itr?的主要内容,如果未能解决你的问题,请参考以下文章

哪个更好,单 for 循环或双 for 循环迭代二维数组? C++

哪个“for”循环具有更好的时间复杂度?

在主键的情况下哪个更好 bigint 或 nvarchar

覆盖向量 C++

坐标系ICRS与ITRS相互转换,时间系统及转换

STL进阶--删除元素