问题描述
我不明白下面的代码。
(来自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
语句。
有人可以在示例代码中向我解释first
和last
的语法和含义吗?
first
迭代器似乎是用初始值std::cin
构造的,但是in()
用作最后一个值有什么用?
我也无法理解_1
部分。
解决方法
首先对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) << " ";
}
,
有人可以在示例代码中向我解释
first
和last
的语法和含义吗?
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
初始化迭代器,将流的地址存储在数据成员中,并从输入流中进行第一次读取以初始化缓存的值数据成员。
而且我也无法理解
_1
部分。
此操作是用迭代序列中的每个元素替换 placeholder _1
并将其乘以3,并使用输出流中的结果,在给定一元函数参数。
for_each(a.begin(),a.end(),std::cout << _1 << ' ');
表达式
std::cout << _1 << ' '
定义一元函数对象。变量_1
是此函数的参数,是实际参数的占位符。在for_each
的每次迭代中,将使用a
的元素作为实际参数来调用该函数。将该实际参数替换为占位符,并评估函数的“主体”。