2014-02-20 18 views
0

香草提出了一个方法来遍历向量:Exception C++第1章第1部分的copy()算法如何工作?

for(vector<int>::iterator i = v.begin(); i < v.end(); i++) { 
cout << *i << endl; 
} 

他替换此代码:

copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n")); 

我努力理解如何,或者为什么这个工程。我抬起头,复印功能和文件说,它相当于:“当我们*输出迭代会发生什么”

template<class InputIterator, class OutputIterator> 
    OutputIterator copy (InputIterator first, InputIterator last, 
         OutputIterator result) 
{ 
    while (first!=last) { 
    *result = *first; 
    ++result; ++first; 
    } 
    return result; 
} 

所以我公司开发的问题,

reference operator*() const; 

Dereference iterator 
Returns *this. 

这就是我困惑的地方。我没有看到OutputIterator指向什么的定义。此外,我看不到*result = *first;如何可能转化为调用cout << *i;

+2

看看ostream_iterator。它的运算符=()会发挥魔力。 –

+0

顺便说一句:这是关于如何使用算法的一个很好的例子,但是在C++ 11'for(const auto&obj:myObjVector){std :: cout << obj << std :: endl; }'因其简单性而被推荐。 – stefaanv

回答

5

您只查找OutputIterator做什么。 OutputIterator只是标准库中一堆类型满足的一组要求。其中一种类型是std::ostream_iterator,因此您需要查看std::copy中的行为。

所以在复制算法中,我们在做*result = *first。首先,operator*std::ostream_iterator什么都不做 - 它只是返回迭代器本身。当我们分配给这个迭代器时,会发生奇迹。如果你查找std::ostream_iterator::operator=,你会发现分配给这个迭代器将会插入(使用<<)到它所构建的流中。因此,您案例中的任务将流入std::cout

此后,resultfirst增加。递增resultstd::ostream_iterator)不起作用,递增first将移动到矢量中的下一个元素。然后在下一次迭代中,下一个元素再次插入到std::cout中,依此类推。

正如你所看到的,std::ostream_iterator并不像你期望的典型迭代器的行为方式那样运行(通过对它们执行间接寻址的元素序列,从而为你提供当前元素)。但它确实符合OutputIterator的要求,所以可以作为一个使用。


下面是std::ostream_iterator::operator=从的libstdc实施++:

/// Writes @a value to underlying ostream using operator<<. If 
/// constructed with delimiter string, writes delimiter to ostream. 
ostream_iterator& 
operator=(const _Tp& __value) 
{ 
    __glibcxx_requires_cond(_M_stream != 0, 
          _M_message(__gnu_debug::__msg_output_ostream) 
          ._M_iterator(*this)); 
    *_M_stream << __value; 
    if (_M_string) *_M_stream << _M_string; 
    return *this; 
} 

忽略第一行的断言,我们可以看到,它然后插入__value到其内部_M_stream流。然后,如果存在分隔符集合_M_string,则它也会插入到_M_stream中。然后它返回。

相关问题