我无法理解 std::istream_iterator 的用法

Cha*_*Kim 3 c++ boost iterator istream-iterator

我无法理解下面的代码。

(来自https://www.boost.org/doc/libs/1_74_0/more/getting_started/unix-variants.html

#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
    using namespace boost::lambda;
    typedef std::istream_iterator<int> in;

    std::for_each(
        in(std::cin), in(), std::cout << (_1 * 3) << " " );
}
Run Code Online (Sandbox Code Playgroud)

该网页没有对代码进行任何解释。

我无法理解的是功能线std::for_each

std::for_each定义如下。

template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn);
Run Code Online (Sandbox Code Playgroud)

所以first就是in(std::cin)last就是in(),就是function这个cout陈述。

谁能向我解释示例代码中的语法和含义firstlast

迭代first器似乎是用初始值构造的,但是最后一个值std::cin有什么用呢?in()

我也无法理解该_1部分。

该程序输出3 *我输入的任意数量的整数值。

Som*_*ude 6

首先对函数进行一些解释std::for_each

该函数从头到尾循环遍历一组迭代器,为范围内的每个元素调用一个函数。

如果你有一个整数向量:

std::vector<int> v = { 1, 2, 3, 4 };
Run Code Online (Sandbox Code Playgroud)

并想打印它们,那么你可以这样做:

std::for_each(v.begin(), v.end(), [](int val) { std::cout << val; });
Run Code Online (Sandbox Code Playgroud)

上面的调用std::for_each相当于:

for (auto i = v.begin(); i != v.end(); ++i)
{
    std::cout << *i;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们使用std::istream_iterator问题中的 the ,它会>>使用迭代器包装输入运算符。

使用标准 C++ lambda重写调用std::for_each,如下所示:

std::for_each(in(std::cin), in(), [](int value) { std::cout << (value * 3) << " " ); });
Run Code Online (Sandbox Code Playgroud)

如果我们将其转换为“正常”for迭代器循环,那么它就会变成:

for (auto i = in(std::cin); i != in(); ++i)
{
    std::cout << (*i * 3) << " ";
}
Run Code Online (Sandbox Code Playgroud)

它的作用是从 读取整数输入(直到文件结束或出现错误)std::cin,然后输出乘以3空格的值。


如果您想知道in(std::cin)and in(),您必须记住这in是 type 的别名std::istream_iterator<int>

这意味着in(std::cin)与 相同std::istream_iterator<int>(std::cin)。即它创建一个std::istream_iterator<int>对象,并传递std::cin给构造函数。并in()构造一个结束迭代器对象。

更清楚地说,代码相当于:

std::istream_iterator<int> the_beginning(std::cin);
std::istream_iterator<int> the_end;  // Default construct, becomes the "end" iterator

for (std::istream_iterator<int> i = the_beginning; i != the_end; ++i)
{
    int value = *i;  // Dereference iterator to get its value
                     // (effectively the same as std::cin >> value)

    std::cout << (value * 3) << " ";
}
Run Code Online (Sandbox Code Playgroud)