Вопрос

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.

Это было полезно?

Решение

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top