繁体   English   中英

std :: transform中的[] const_iterator :: value_type是什么意思

[英]what does [] const_iterator::value_type in std::transform mean

具体来说这里是代码。 第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;
}

表达式[](CI:value_type n) { return ++n; } [](CI:value_type n) { return ++n; }是λ函数。 空括号表示它不访问当前范围的任何成员。

transform基本上将此函数应用于输入序列(l)的每个元素,并将其写入输出序列(也是l)。 由于--ce,它在到达最后一个元素之前停止。

代码接受l之后的一个元素并将其递增到l的下一个元素(因为++ b)。 因此你得到0,1,2,3,4。

如果将cb更改为++ cb,则得到0,1,1,1,0,因为那时,从索引为1的元素开始,然后将每个元素递增到最后一个。

在这里找到有关lambdas的一些信息。

std :: transform的解释

在这个声明中

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指向的列表的第二个元素中。 之后, cbb在变换体内递增。

所以在第一次迭代之后,列表看起来像

    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然后cbb将指向相同的元素,并且算法将简单地用从列表的第二个元素开始的递增值重写每个元素,因为使用了iterator ++cb 结果将是0,1,1,1,0

首先,您需要了解语法:方括号表示您的lambda函数没有从其周围的上下文中捕获任何内容。 基本上,这是将一段逻辑插入到std::transform调用中的简洁方法:您告诉函数转换值意味着向其中添加一个值。

为了进一步了解正在发生的事情,并解释01110输出,让我们看看std::transform作用:它从cb (初始元素)到--ce (后面的第二个元素),包括,调用lambda函数,并将返回的结果放入从++b开始的单元格中,即在索引1,2,3等处。

第一次迭代从L[0]取零,加1,并将1写入L[1] 第二次迭代从之前拾取1 ,加1,并将2写入L[2] 迭代继续,直到std::transform4写入L[4]

然而,当你用++cb替换cb时,写入被执行到读取数据的同一个单元格,即L[1]被赋值0+1 ,然后L[2]被赋值0+1 ,然后L[3]被赋值为0+1 ,然后循环达到--ce ,然后停止。

请注意, ++n是不必要的,因为一旦lambda调用结束,递增n的副作用就会消失。 你可以用n+1表达式替换它,它没有副作用:

std::transform(cb, --ce, ++b, [] (CI::value_type n) { return n+1; });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM