std::反向使用反向迭代器,为什么不是无操作?
std::reverse with reverse iterators, why isn't it a no-op?
举一个最小的例子:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string s{"abcde"};
std::reverse(s.rbegin(), s.rend());
std::cout << s;
}
由于我们正在反转一系列反向迭代器,我希望它是一个no-op。但它打印edcba
。我对反向迭代器或std::reverse
有什么不了解?
在这种情况下,交换操作是对称的,所以从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与abcda
- 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
。
算法对范围进行操作。std::reverse
完成了它的工作,[s.rbegin()
,s.rend()
)现在是"abcde"
。std::cout << s;
将从另一端打印它,所以"edcba"
.
还好,
最后使用了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);
}
相关文章:
- 为什么不;名字在地图上是按顺序排列的吗
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 为什么不递增?(构造函数)
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 为什么不允许使用可变长度数组作为向量元素?
- C++:为什么不调用移动构造函数?
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 为什么不能用常量表达式声明数组?
- 为什么不能直接引用作用域枚举类成员,而不能为无作用域枚举生成类成员?
- C++ queue.front();为什么不从第一个元素开始呢?
- 为什么不允许这种交叉广播?
- 为什么三元操作失败不咳嗽
- C++为什么不可能将这两个操作合并在一行中?
- std::反向使用反向迭代器,为什么不是无操作?
- 为什么c++并发操作listing_6.1不使用std::recursive_mutex
- 为什么不能对C++中的数组执行聚合操作?
- 为什么不为定义了析构函数的类合成move操作呢?
- 为什么提取操作不工作