2013-04-29 55 views
7

根据大多数C++引用,例如cplusplus.com,forward iterators不需要是可分配的(我的意思是,推定为左值)。然而,对于需要编写值几个STL算法,例如std::fill(也std::generate等),该规范使用前向迭代:STL填充和转发迭代器

template <class ForwardIterator, class T> 
    void fill (ForwardIterator first, ForwardIterator last, const T& val); 

而等效行为,需要左值解除引用:

template <class ForwardIterator, class T> 
    void fill (ForwardIterator first, ForwardIterator last, const T& val) 
{ 
    while (first != last) { 
    *first = val; 
    ++first; 
    } 
} 

所以,它实际上使用了一次可变的前向迭代器。

现在的问题是:

(1)为什么不说清楚,在这些情况下使用的前向迭代器是可变的?

(2)更新:我发现下面的问题很愚蠢:我暂时忘了输出迭代器不需要支持相等比较。无论如何,上述问题依然存在。

为什么用std::fillstd::generate等等,而不是实际上需要多次通过使用正向迭代器,而不是输出迭代器? (std::copy只需要输出迭代,比如,什么道理呢?)

+0

'前向迭代器不需要可分配',你是如何确定的?我很确定他们是可分配的。 – 2013-04-29 23:57:44

+0

@JesseGood出于实用目的,它们几乎总是可分配的,但如果您阅读了参考文献http://cplusplus.com/reference/iterator/ForwardIterator/?kw=forward%20iterator,则不是。 – 4ae1e1 2013-04-30 00:01:17

+1

@JesseGood我也在SO上发现了这个:http://stackoverflow.com/questions/14058642/are-forward-iterators-output-iterators – 4ae1e1 2013-04-30 00:03:11

回答

5

从签名

template <class ForwardIterator, class T> 
void fill (ForwardIterator first, ForwardIterator last, const T& val); 

你不能推断ForwardIteratorforward iterator描述的迭代器。但是,如果你读的参数说明,你会发现,firstlast必须

Forward Iterators的最初和最后的位置在支持被分配T类型的价值元素的序列。

(强调我)。因此,只满足前向迭代器所需要的前向迭代器不是一个有效的参数。

+0

是的,这是一个很好的观点。但从标准的角度来看签名是棘手的。 – 4ae1e1 2013-04-30 00:27:46

+0

另一种方法是为前向迭代器引入一个新的名称,该名称支持指向元素的分配。 – Oswald 2013-04-30 00:33:50

1

对我来说这似乎并不奇怪,因为fill的规范是(取消引用的)迭代器可从T分配。输出迭代器将不足以用于确定范围结束,因此选择了具有要求的forward_iterator

你会注意到,fill_n确实使用输出迭代,因为不需要迭代器比较,以确定序列的末端,以填补。

+0

我认为OP的观点是前向迭代器的概念是* required *但不*足够*来指定参数类型的需求。这同样适用于“输出迭代器”;只有通过要求参数是*两者*才能得到正确的语义。换句话说,有不能调用'std :: fill'的前向迭代器。 – 2013-04-30 01:21:15