我不明白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);

所以firstin(std::cin)last只是in()functioncout语句。

有人可以在示例代码中向我解释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读取整数输入(直到文件结尾或错误),然后输出乘以3和一个空格的值。


如果您想知道in(std::cin)in(),则必须记住in是类型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) << " ";
}
,

有人可以在示例代码中向我解释firstlast的语法和含义吗?

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

如果查看std::istream_iterator的构造函数的描述,您会发现in()构造了流结束迭代器。

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

构造流结束迭代器,值初始化存储的值。如果定义constexpr中的初始化程序是常量初始化程序(自C ++ 11起),则此构造函数为auto x = T();

关于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

初始化迭代器,将流的地址存储在数据成员中,并从输入流中进行第一次读取以初始化缓存的值数据成员。

source

而且我也无法理解_1部分

此操作是用迭代序列中的每个元素替换 placeholder _1并将其乘以3,并使用输出流中的结果,在给定一元函数参数。

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

表达式std::cout << _1 << ' '定义一元函数对象。变量_1是此函数的参数,是实际参数的占位符。在for_each的每次迭代中,将使用a的元素作为实际参数来调用该函数。将该实际参数替换为占位符,并评估函数的“主体”。

source