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()
to 范围内的每个元素ivec.end()
,生成一系列值,然后将这些值写回从 开始的范围ivec.begin()
。这意味着它使用通过将函数应用于每个数组元素而产生的值范围覆盖范围的原始内容,因此元素被覆盖而不是就地修改。不过,净效果与原始效果相同for_each
。
希望这可以帮助!