练习10.38
列出5个迭代器类别,以及每类迭代器所支持的操作。
解答:
下面把 迭代器类别 这节抄一下,避免手边没有书的时候。
【引用】
输入迭代器(input inserator)
可以读取序列中的元素。一个输入迭代器必须支持
1. 用于比较两个迭代器的相等和不相等运算(==,!=)
2. 用于推进迭代器的前置和后置递增运算(++)
3. 用于读取元素的解引用运算符(*);解引用智慧出现在复制运算符右侧
4. 箭头运算符(->),等价(*it).member,即,解引用迭代器,并提取对象的成员
输入迭代器只用于顺序访问。
对于一个输入迭代器,*it++保证是有效的,但递增它可能导致所有其他指向流的迭代器失效。
其结果就是,不能保证输入迭代器的状态可以保存下来并用来访问元素。
因此,输入迭代器只能用于单遍扫描算法。
算法find和accumulate要求输入迭代器;而istream_iterator是一种输入迭代器。
输出迭代器(output iterator)
可以看作输入迭代器功能上的补集——只写而不读元素。
输入迭代器必须支持:
1. 用于推进迭代器的前置和后置递增运算(++)
2. 解引用运算符(*),只出现在复制运算符的左侧(向一个已经解引用的输出迭代器赋值,就是将值写入它所指向的元素)
我们只能想一个输入迭代器复制一次。
类似输入迭代器,输出迭代器只能用于单遍扫描算法。
用作目的位置的迭代器通常都是输出迭代器。
例如,copy函数第三个参数就是输出迭代器。
ostream_iterator类型也是输出迭代器。
前向迭代器(forward iterator)
可以读写元素。这类迭代器只能在序列中沿一个方向移动。
前向迭代器支持所有输入和输出迭代器的操作,而且可以多次读写同一个元素。
因此,我们可以保存前向迭代器的状态,使用前向迭代器的算法可以对序列进行多遍扫描。
算法replace要求前向迭代器,forward_list上的迭代器是前向迭代器。
双向迭代器(bidirectional iterator)
可以正向/反向读写序列中的元素。除了支持所有前向迭代器的操作之外,双向迭代器还支持前置和后置递减运算符(--)。
算法reverse要求双向迭代器,除了forward_list之外,其他标准库都提供符合双向迭代器要求的迭代器。
随机访问迭代器(random-access iterator)
提供在常量时间内访问序列中任意元素的能力。
此类迭代器支持双向迭代器的所有功能,此外还支持表3.7(第99页)中的操作:
1. 用于比较两个迭代器相对位置的关系运算符(<、<=、>和>=)
2. 迭代器和一个整数值的加减运算(+、+=、-和-=),计算结果是迭代器在序列中前进(或后退)给定整数个元素后的位置
3. 用于两个迭代器上的减法运算符(-),得到两个迭代器的距离
4. 下标运算符(iter[n]),与*(iter[n])等价
算法sort要求随机访问迭代器。
array、deque、string和vector的迭代器都是随机访问迭代器,用于访问内置数组元素的指针也是。
练习10.39
list上的迭代器属于哪类? vector呢?
解答:
list 双向迭代器
vector 随机访问迭代器
练习10.40
你认为copy要求哪类迭代器? reverse和unique呢?
解答:
template<class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
while (first!=last) {
*result = *first;
++result; ++first;
}
return result;
}
从copy的等价行为上就可以看出来,输入/输出迭代器。
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
while ((first!=last)&&(first!=--last)) {
std::iter_swap (first,last);
++first;
}
}
reverse的等价行为,双向迭代器。
template <class ForwardIterator>
ForwardIterator unique (ForwardIterator first, ForwardIterator last)
{
if (first==last) return last;
ForwardIterator result = first;
while (++first != last)
{
if (!(*result == *first)) // or: if (!pred(*result,*first)) for version (2)
*(++result)=*first;
}
return ++result;
}
unique的等价行为,前向迭代器。