std :: reverse with reverse iterators,为什么不是no-op?

时间:2016-06-02 04:09:30

标签: c++

以这个最小的例子:

#include <iostream>
#include <string>
#include <algorithm>

int main()
{
    std::string s{"abcde"};
    std::reverse(s.rbegin(), s.rend());
    std::cout << s;
}

由于我们正在逆转一系列反向迭代器,我希望它是一个无操作。但它会打印edcba。关于反向迭代器或std::reverse我不了解什么?

3 个答案:

答案 0 :(得分:1)

算法在范围上运行。 std::reverse完成了工作,[s.rbegin()s.rend())现在"abcde"std::cout << s;会从另一端打印出来,"edcba"

答案 1 :(得分:1)

在这种情况下,交换操作是对称的,因此无论您是从s.begin()转到s.end()还是从s.rbegin()转到s.rend()都无关紧要。

要想象这一点,首先考虑一下前进时会发生什么(从s.begin()s.end()),使用 abcde 的例子:

  • a e 交换。该字符串现在是 ebcda
  • b d 交换。该字符串现在是 edcba

逆转现在已经完成( c 位于中间且不需要移动)。

现在考虑倒退时会发生什么(从s.rbegin()s.rend()):

  • e a 交换。该字符串现在是 ebcda
  • d b 交换。该字符串现在是 edcba

最终结果是相同的,因为交换是对称的。

根据C ++标准:

  

25.3.10反向 [alg.reverse]

template<class BidirectionalIterator>
void reverse(BidirectionalIterator first, BidirectionalIterator last);
     

效果:对于每个非负整数i < (last - first) / 2,将iter_swap应用于所有迭代器对first + i(last - i) - 1

答案 2 :(得分:0)

没关系,
最后它使用swap(* _ Left,* _Right);所以它改变了原来的字符串s
看到来源:

template<class _BidIt> inline
    void reverse(_BidIt _First, _BidIt _Last)
    {   // reverse elements in [_First, _Last)
    _DEBUG_RANGE(_First, _Last);
    _Reverse(_Unchecked(_First), _Unchecked(_Last), _Iter_cat(_First));
    }
template<class _BidIt> inline
    void _Reverse(_BidIt _First, _BidIt _Last, bidirectional_iterator_tag)
    {   // reverse elements in [_First, _Last), bidirectional iterators
    for (; _First != _Last && _First != --_Last; ++_First)
        _STD iter_swap(_First, _Last);
    }
template<class _FwdIt1,
    class _FwdIt2> inline
    void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right)
    {   // swap *_Left and *_Right
    swap(*_Left, *_Right);
    }