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

I can't understand the use of std::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) << " " );
}

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

我无法理解的是带有std::for_each函数的那一行。

std::for_each定义如下。

template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn);

所以first就是in(std::cin)last就是in()function就是cout语句。

谁能给我解释一下示例代码中firstlast的语法和含义?

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

我也看不懂 _1 部分。

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

首先解释一下 std::for_each 函数。

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

如果你有,例如整数向量:

std::vector<int> v = { 1, 2, 3, 4 };

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

std::for_each(v.begin(), v.end(), [](int val) { std::cout << val; });

上面对std::for_each的调用等同于:

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

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

使用标准 C++ lambda 重写 std::for_each 调用,它看起来像这样:

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

如果我们将其转换为“正常”for 迭代器循环,则它变为:

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

它的作用是从 std::cin 读取整数输入(直到 end-of-file 或错误),然后输出乘以 3 和 space 的值.


如果您想知道 in(std::cin)in(),您必须记住 in 是类型 std::istream_iterator<int>.

的别名

这意味着 in(std::cin)std::istream_iterator<int>(std::cin) 相同。 IE。它创建一个 std::istream_iterator<int> 对象,并将 std::cin 传递给构造函数。 in() 构造一个 end-iterator 对象。

更清楚,代码等同于:

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) << " ";
}

Could anyone explain to me the syntax of first and last syntax and meaning in the example code?

The first iterator seems to be constructed with initial value std::cin, but what's the use of in() for the last value?

如果您查看 std::istream_iterator 构造函数的描述,您会发现 in() 构造了 end-of-stream 迭代器。

istream_iterator(); //  < C++11
constexpr istream_iterator(); // > C++11

Constructs the end-of-stream iterator, value-initializes the stored value. This constructor is constexpr if the initializer in the definition auto x = T(); is a constant initializer (since C++11).

至于in(std::cin):

istream_iterator( istream_type& stream );
istream_iterator( const istream_iterator& other );  //< C++11
istream_iterator( const istream_iterator& other ) = default; // > C++11

Initializes the iterator, stores the address of stream in a data member, and performs the first read from the input stream to initialize the cached value data member.

source

And I also can't understand the _1 part.

这样做是用迭代序列中的每个元素替换 placeholder _1 并将其乘以 3,使用输出流中的结果,如它应该,给定一元函数参数。

for_each(a.begin(), a.end(), std::cout << _1 << ' ');

The expression std::cout << _1 << ' ' defines a unary function object. The variable _1 is the parameter of this function, a placeholder for the actual argument. Within each iteration of for_each, the function is called with an element of a as the actual argument. This actual argument is substituted for the placeholder, and the “body” of the function is evaluated.

source