2014-05-08 8 views
0

je lis here et aussi here et des exemples sur cpluplus.com Et je ne comprends toujours pas comment cela fonctionnesyntaxe Lambda avec des algorithmes

ce qui me brouille au plus comment lambdas fonctionnent avec des algorithmes de _Si comme copy_if qu'ils don Conteneurs de référence dans le corps

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

ne fait pas référence à l'objet vectoriel foo dans le corps. alors comment il effectue l'action souhaitée?

De plus, je ne comprends pas quelle est la différence beetween la capture d'une variable et en passant comme paramètre

J'ai aussi essayé de mon propre exemple:

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 

Il compile (MVS 2010 avec Intel Compositeur 14) mais produit des déchets et des erreurs d'assertion.

+1

Il ne fait pas référence le vecteur parce qu'il passe ses valeurs individuelles 1 à la fois dans votre fonction lambda pour vous de vérifier. – CoffeeandCode

+0

comment ça marche. ce n'est pas clair pour moi –

+0

Il pourrait le faire comme bon lui semble. Il pourrait simplement faire un simple 'pour (taille_t n = 0; n CoffeeandCode

Répondre

0

Si vous regardez le code source std :: copy_if, vous devriez voir comment cela fonctionne.

Essentiellement ce que copy_if fait est ceci:

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

Il ne connaît pas les conteneurs, ni le faire. La paire d'itérateurs (f1, l1) spécifie une plage dans laquelle les éléments sont copiés, les itérateurs contiennent toutes les connaissances sur la façon d'accéder à l'élément. L'itérateur f2 spécifie le point de départ de la plage de destination. Si la plage de destination n'est pas assez grande, il y aura un bug de débordement de tampon. Le prédicat est une fonction qui indique s'il faut copier un élément ou non. Il n'a pas besoin de savoir quoi que ce soit sur le conteneur, il doit seulement pouvoir dire à copy_if si un élément visité doit être copié ou non.

La différence entre la capture d'une variable et la transmission en tant qu'argument doit être expliquée par les extraits suivants. Ce lambda

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

signifie essentiellement ceci:

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

    int captured_; 
} functor(captured); 
0

Vous effacez du vecteur v2 en utilisant les itérateurs du conteneur v1. Cela devrait vous donner des résultats de merde - c'est un comportement indéfini.

+0

Merci de ne pas l'avoir remarqué. J'ai encore besoin d'explications pour les deux premières questions –