for_each and transform

for_each and transform

本文关键字:transform and each for      更新时间:2023-10-16
for_each(ivec.begin(),ivec.end(),
        []( int& a)->void{ a = a < 0 ? -a : a; 
    });
transform(ivec.begin(),ivec.end(),ivec.begin(),
        [](int a){return a < 0 ? -a : a;
    });

我目前正在学习lambda,我很好奇我上面发布的两个实现是如何不同的?

您所展示的两个实现在逻辑上没有不同(假设您通过添加一个返回而使第一个版本正确)。第一个脚本修改了现有的元素,而最后一个脚本用新值覆盖了它的元素。

我看到的最大区别是,对于transform,您可以传递abs而不是重新实现它的lambda。

transform在函数式语言中被称为map。也就是说,它对输入范围中的每个元素应用一个函数,并将输出存储到输出范围中。(因此通常不打算修改输入,而是存储一系列输出)

for_each简单地丢弃应用函数的返回值(因此它可能修改输入)。

这是主要的区别。它们很相似,但目的不同。

第一个版本:

for_each(ivec.begin(),ivec.end(),
      []( int& a)->void{ a = a < 0 ? -a : a; 
});

通过调用lambda函数

来工作
 []( int& a)->void{ a = a < 0 ? -a : a; }

表示范围内的每个元素一次,并将范围内的元素作为参数传递。相应地,它通过直接更改元素的值来就地更新元素。

第二个版本:

transform(ivec.begin(),ivec.end(),ivec.begin(),
    [](int a){return a < 0 ? -a : a;
});

通过应用lambda函数

工作
[](int a){return a < 0 ? -a : a;}
ivec.begin()ivec.end()范围内的每个元素进行

操作,生成一系列值,然后将这些值写回从ivec.begin()开始的范围。这意味着它将使用通过将函数应用于每个数组元素而产生的值范围来覆盖范围的原始内容,因此元素被覆盖而不是就地修改。但是,最终效果与原始for_each相同。

希望这对你有帮助!