C++ 为什么std::advance不返回结果迭代器?

C++ 为什么std::advance不返回结果迭代器?,c++,iterator,c++-standard-library,C++,Iterator,C++ Standard Library,目前,std::advance的设计如下: template< class InputIt, class Distance > void advance( InputIt& it, Distance n ); 模板 无效提前(输入和输入,距离n); 然而,我经常发现自己想要这样的东西: template< class InputIt, class Distance > InputIt advance( InputIt it, Distance n ); 模板

目前,
std::advance
的设计如下:

template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );
模板<类输入,类距离>
无效提前(输入和输入,距离n);
然而,我经常发现自己想要这样的东西:

template< class InputIt, class Distance >
InputIt advance( InputIt it, Distance n );
模板<类输入,类距离>
输入前进(输入它,距离n);

那么,当前设计背后的基本原理是什么?这是出于性能考虑吗?请注意,
std::next
std::prev
确实返回结果迭代器。

没有技术原因阻止它返回对输入值的引用,如果不使用,任何合理的编译器都应该能够优化返回值。所以如果他们愿意,他们可以这样做

我认为从API设计的角度来看,他们的选择是有意义的,尽管-
std::prev
std::next
使用迭代器并分别返回指向上一个或下一个元素的不同迭代器,而不修改输入

另一方面,std::advance修改输入。如果它返回了对输入迭代器的引用,那么对于返回副本而不修改输入的函数,可能会产生混淆。这可能是危险的

请注意,
std::advance
inputierator
s一起工作,其中包括迭代有副作用的迭代器(例如从流中读取的迭代器),但
std::prev
std::next
仅与
ForwardIterator
s一起工作,后者没有副作用


因此,返回一个单独的值(如
std::prev
std::next
)将是一个坏主意-最终在同一个流上会有两个迭代器,这可能会对彼此产生不利影响。

注释部分中指出的主要原因是,an不能保证在增加迭代器之后,以前的任何迭代器仍然有效:

InputIterator仅保证单次传递算法的有效性:一旦InputIterator i递增,其先前值的所有副本都可能无效

因此,如果返回一个副本,调用方可能会得到两个迭代器,其中一个迭代器可能无效。带有引用的接口表明这不是应该使用输入迭代器的方式

另一方面,以a为例,除其他外,满足a的要求:

与inputierator和outputierator不同,它可以用于多路径算法

因此,您可以移动迭代器,同时仍保留其先前位置的副本

是一个很好的表,它清楚地显示了不同迭代器概念之间的关系


当然,有人可能会说,调用者应该知道InputIterator是如何工作的,并且应该允许调用者方便地选择适合其当前需要的版本。此类问题的一个示例由以下人员在评论部分中介绍:

然而,取悦每个人总是导致接口中方法数量的爆炸


该链接表明,现在是一种有待达成共识的状态。

我认为这种设计是支持输入迭代器所必需的
std::next
std::prev
相应地需要正向和双向迭代器。我相信他们没有想到会这样设计。。。。与其他许多事情一样。
std::next
不会更改传递给它的迭代器,它会返回指向集合中下一个元素的另一个迭代器。这不是输入迭代器的选择。注意C++不允许您编写自己的<代码> STD::前进< /代码>或版本之上。考虑<代码>提前/代码>作为底层的低层次实现抽象,使用诸如“代码>下一个< /代码>”的高级便利功能。两者都有各自的位置。这并不是一个合理的解释——你只是在重复显而易见的事实。整个答案归结为“他们本可以做,但他们没有”。@BartoszKP他们本可以做,但他们没有,因为这是个坏主意。我的回答解释了为什么这是一个坏主意。例如,第三段是一个适用于任何函数的小事,而不仅仅是
std::advance
。如果
std::prev
接受了一个引用,您可以对它说完全相同的话-返回引用可能会与返回copy而不修改输入的函数混淆。只有关于输入和转发迭代器的段落(您刚刚添加的)是相关的。所以,现在看起来还可以(虽然我会删除所有其他部分,因为它们只是噪音,很难找到重点,这只是在第4段)-我将删除我的评论。干杯不知何故,我认为std::prev不能在ForwardIterator上工作(需要双向Iterator)