Lambda语法与算法

时间:2014-05-08 00:41:57

标签: c++11 lambda stl-algorithm

我在cpluplus.com上阅读了herehere以及示例 我仍然不明白它是如何运作的

最让我感到困惑的是lambdas如何使用_if算法(如copy_if)来表示他们不会在身体中引用容器

     std::vector<int> foo = {25,15,5,-5,-15};
         std::vector<int> bar (foo.size());

          // copy only positive numbers:
          auto it = std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i)
        {return !(i<0);} )

不会在体内引用矢量对象foo。那么它如何执行所需的动作?

此外,我不明白捕获变量和传递参数之间的区别是什么

我也尝试了自己的例子:

vector<unsigned long>v2(10);
for(unsigned long i=0;i<v2.size();i++)
    v2[i]=10-i;
v2.erase(remove_if(v1.begin(), v1.end(),[](unsigned long n) { 

    return n%2==1; } ),v2.end());//remove odd numbers

它编译(MVS 2010与英特尔Composer 14)但产生垃圾和断言错误。

2 个答案:

答案 0 :(得分:0)

使用容器v1中的迭代器从vector v2中删除。预计这会给你废话结果 - 这是未定义的行为。

答案 1 :(得分:0)

如果你看一下std :: copy_if源代码,你应该看看它是如何工作的。

基本上copy_if的作用是:

void copy_if(It1 f1, It1 l1, It2 f2, Pred pred) {
  for (; f1 != l1; ++f1) {
    if (pred(*f1)) {
      *f2 = *f1;
      ++f2;
    }
  }
}

它不知道容器,也不知道。迭代器对(f1,l1)指定从中复制项的范围,迭代器包含有关如何到达元素的所有知识。迭代器f2指定目标范围的起始点。如果目标范围不够大,那么woul会出现缓冲区溢出错误。谓词是一个指示是否复制元素的函数。它不需要知道有关容器的任何信息,它只需要能够告诉copy_if是否应该复制被访问的元素。

捕获变量和作为参数传递之间的区别应该由以下片段解释。这个lambda

int captured = 42;
auto functor = [captured](int x) { return x%2 == 0; };

基本上意味着:

    int captured = 42;
struct Blah
{
    Blah(int c) : captured_(c) { }
    bool operator()(int x) const { return x%2 == 0; }

    int captured_;
} functor(captured);