具体来说这里是代码。第15行是做什么的(调用转换)?
有人可以解释为什么输出01234?另一方面,如果我在第15行将cb更改为++ cb,则输出01110.第15行的返回值是什么?
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
int main()
{
typedef std::list<int> L;
L l(5);
typedef L::const_iterator CI;
CI cb = l.begin(), ce = l.end();
typedef L::iterator I;
I b = l.begin();
std::transform(cb, --ce, ++b, [] (CI::value_type n) { return ++n; });
std::copy(l.begin(), l.end(), std::ostream_iterator<CI::value_type>(std::cout));
std::cout << std::endl;
return 0;
}
答案 0 :(得分:4)
表达式[](CI:value_type n) { return ++n; }
是一个lambda函数。空括号表示它不访问当前范围的任何成员。
transform基本上将此函数应用于输入序列(l)的每个元素,并将其写入输出序列(也是l)。由于--ce。
,它在到达最后一个元素之前停止代码接受l之后的一个元素并将其递增到l的下一个元素(因为++ b)。因此你得到0,1,2,3,4。
如果你将cb更改为++ cb,你会得到0,1,1,1,0,因为那样,你从索引为1的元素开始,只是递增每一个直到最后一个。
答案 1 :(得分:2)
在本声明中
L l(5);
创建了一个包含5个元素的列表,每个元素都由0初始化。
在此次电话会议中
std::transform(cb, --ce, ++b, [] (CI::value_type n) { return ++n; });
cb
指向列表的第一个元素。 --ce
在评估之后,递减运算符指向列表的最后一个元素。
因此cb
和--ce
设置列表元素的范围
[cb, --ce)
其中括号表示--ce
未包含在范围内。
++b
。
你有
b
|
0 0 0 0 0
^ ^
| |
cb ce
cb指向的值是列表中第一个元素的值,在lambda表达式中增加
[] (CI::value_type n) { return ++n; }
并写在迭代器b指向的列表的第二个元素中。之后cb
和b
在变换体内递增。
所以在第一次迭代之后,列表看起来像
b
|
0 1 0 0 0
^ ^
| |
cb ce
现在cb
指向列表的第二个元素。它的值在lambda表达式中递增,并写在迭代器b
指向的第三个元素中。
b
|
0 1 2 0 0
^ ^
| |
cb ce
因此,您将获得该列表将具有值0,1,2,3,4。
如果您要编写算法的调用,如
std::transform(++cb, --ce, ++b, [] (CI::value_type n) { return ++n; });
正在使用++cb
然后cb
和b
将指向相同的元素,并且算法将简单地使用从列表的第二个元素开始的递增值重写每个元素,因为使用了迭代器++cb
。
结果将是0,1,1,1,0
答案 2 :(得分:1)
首先,您需要了解语法:方括号表示您的 lambda函数没有从其周围的上下文中捕获任何内容。基本上,这是一种将一段逻辑插入std::transform
调用的简洁方法:您告诉函数转换值意味着向其中添加一个。
为了进一步了解正在发生的事情,并解释01110
输出,让我们看看std::transform
做了什么:它将cb
(初始元素)中的项目带到{ {1}}(后面的第二个元素)(包括在内)调用lambda函数,并将返回的结果放入从--ce
开始的单元格中,即索引1,2,3等等。 / p>
第一次迭代从++b
取零,加一,并将L[0]
写入1
。第二次迭代从之前获取L[1]
,添加一个,并将1
写入2
。迭代一直持续到L[2]
将std::transform
写入4
。
然而,当您将L[4]
替换为cb
时,会将写入执行到从中读取数据的同一个单元格,即++cb
被分配L[1]
,然后0+1
被分配L[2]
,然后0+1
被分配L[3]
,然后循环到达0+1
,然后停止。
请注意,--ce
是不必要的,因为一旦lambda调用结束,递增++n
的副作用就会消失。您可以将其替换为n
表达式,该表达式没有副作用:
n+1