Question

I read here and also here and examples on cpluplus.com And I still don't understand how it works

what confuses me at most how lambdas work with _if algorithms like copy_if that they don't reference containers in the body

     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);} )

doesn't reference vector object foo in the body. so how it performs the desired action?

Additionally, I don't understand what is the difference beetween capturing a variable and passing as parameter

I also tried my own example:

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

It compiles (MVS 2010 with Intel Composer 14) but produces rubbish and assertion error.

Was it helpful?

Solution

If you look at std::copy_if source code, you should see how that works.

Essentially what copy_if does is this:

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

It does not know about containers, nor does it have to. The pair of iterators (f1, l1) specify a range where the items are copied from, the iterators contain all the knowledge about how to get to the element. The iterator f2 specifies the starting point of the destination range. If the destination range is not big enough woul will have a buffer overflow bug. The predicate is a function that indicates whether to copy an element or not. It does not have to know anything about the container, it just needs to be able to tell copy_if whether an element being visited should be copied or not.

Difference between capturing a variable and passing as argument should be explained by the following snippets. This lambda

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

essentially means this:

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

    int captured_;
} functor(captured);

OTHER TIPS

You're erasing from vector v2 using iterators from container v1. This is expected to.give you crap results - it's undefined behaviour.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top