Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/06/2020, à 15:49

chris7522

for_each C++

Bonjour a toutes et a tous,
Que me permet de faire spécifiquement la boucle for_each ? Il n' a pas de double emploi avec la boucle for ?
Merci de vos réponses.

Hors ligne

#2 Le 03/07/2020, à 22:12

Nuliel

Re : for_each C++

Bonjour,
for_each permet de faire une action sur un objet itérable. Il utilise des fonctions de rappel (callback) et est plus compacte que la version boucle for.
for_each peut être plus claire dans des cas comme lorsqu'on itère sur une liste chaînée.

Hors ligne

#3 Le 03/07/2020, à 22:16

chris7522

Re : for_each C++

Merci .
Peux tu me donner un exemple d'utilisation
?

Dernière modification par chris7522 (Le 03/07/2020, à 22:17)

Hors ligne

#4 Le 03/07/2020, à 22:35

NicoApi73

Re : for_each C++

Salut,

Tu as un bel exemple ici : https://en.cppreference.com/w/cpp/algorithm/for_each

#include <vector>
#include <algorithm>
#include <iostream>
 
struct Sum
{
    void operator()(int n) { sum += n; }
    int sum{0};
};
 
int main()
{
    std::vector<int> nums{3, 4, 2, 8, 15, 267};
 
    auto print = [](const int& n) { std::cout << " " << n; };
 
    std::cout << "before:";
    std::for_each(nums.cbegin(), nums.cend(), print);
    std::cout << '\n';
 
    std::for_each(nums.begin(), nums.end(), [](int &n){ n++; });
 
    // calls Sum::operator() for each number
    Sum s = std::for_each(nums.begin(), nums.end(), Sum());
 
    std::cout << "after: ";
    std::for_each(nums.cbegin(), nums.cend(), print);
    std::cout << '\n';
    std::cout << "sum: " << s.sum << '\n';
}

Hors ligne

#5 Le 04/07/2020, à 09:13

chris7522

Re : for_each C++

Merci a vous .
J'ai l'impression qu'on utilise for_each lorsqu'on appele une lambda ou du moins la variable qui contient la lambda .

Hors ligne

#6 Le 04/07/2020, à 09:46

Nuliel

Re : for_each C++

Pas forcément, c'est juste qu'écrire une fonction lambda est plus adapté lorsque la fonction est simple et ne ressert pas
Version sans fonction lambda:

#include <vector>
#include <algorithm>
#include <iostream>
 
struct Sum
{
    void operator()(int n) { sum += n; }
    int sum{0};
};

void print(const int& n)
{
    std::cout << " " << n; 
}

int ajout(int &n)
{ 
    return n++;
}

int main()
{
    std::vector<int> nums{3, 4, 2, 8, 15, 267};
 
    std::cout << "before:";
    std::for_each(nums.cbegin(), nums.cend(), print);
    std::cout << '\n';
 
    std::for_each(nums.begin(), nums.end(), ajout);
 
    // calls Sum::operator() for each number
    Sum s = std::for_each(nums.begin(), nums.end(), Sum());
 
    std::cout << "after: ";
    std::for_each(nums.cbegin(), nums.cend(), print);
    std::cout << '\n';
    std::cout << "sum: " << s.sum << '\n';
}

Par contre je comprends pas la différence entre cbegin() et begin()   (une histoire d'itérateur avec ou sans qualificatif const)

Dernière modification par Nuliel (Le 04/07/2020, à 09:48)

Hors ligne

#7 Le 04/07/2020, à 12:16

chris7522

Re : for_each C++

Merci , pour toutes vos réponses smile
Tu as devancé la question que je voulais poser : Dans quelle situation vais-je  utiliser préférément une lambda a une fonction accessible a tous ?
   Tu viens de donner 2 raisons , mais il y en a t il pas d'autre ?
   Pour revenir a ton exemple , dans la structure , n'etait il pas préférable d'initialiser ta variable sum avant ta fonction ?
  Pour ce qui est de " cbegin " , n'est ce pas ce qui permet de rendre constant le nombre pointé dans ton vector  ?

Dernière modification par chris7522 (Le 04/07/2020, à 12:17)

Hors ligne

#8 Le 04/07/2020, à 12:40

chris7522

Re : for_each C++

Pardonnez moi de passer un peu du coq a l'ane , mais je ne comprends pas ce code , lorsque j'enleve ma variable " un_booléen " de ma zone de capture , ca compile quand meme hmm
  Je croivais que ma fonction lambda ne pouvait pas accéder aux variables de la fonction dans laquelle elle est ecrite sauf si on utilise la zone de capture .

#include <iostream>

int main()
{
    bool const un_booleen { true };
    int const un_entier { 42 };
    double const un_reel { 3.1415 };

    auto lambda = [un_entier, un_reel]() -> void
    {
        std::cout << "Le booléen vaut " << std::boolalpha << un_booleen << "." << std::endl;
        std::cout << "L'entier vaut " << un_entier << "." << std::endl;
        std::cout << "Le réel vaut " << un_reel << "." << std::endl;
    };

    lambda();

    return 0;
}

Hors ligne

#9 Le 04/07/2020, à 17:01

Nuliel

Re : for_each C++

Généralement on utilise presque jamais de fonction lambda, c'est vraiment quand on ne se sert qu'une fois de la fonction et qu'elle est extrêmement simple (du genre incrémenter une variable)
Pour la structure sum, ça change pas grand chose que sum soit défini avant ou après.
Pour cbegin, je ne sais pas (j'imagine que c'est plutôt l'itérateur qui est constant et non ce qui est pointé par l'itérateur)
Aucune idée pour ton programme.

Hors ligne

#10 Le 04/07/2020, à 19:22

NicoApi73

Re : for_each C++

Nuliel a écrit :

Par contre je comprends pas la différence entre cbegin() et begin()   (une histoire d'itérateur avec ou sans qualificatif const)

cbegin renvoie un itérateur const : tu ne peux pas modifier le contenu. http://www.cplusplus.com/reference/vect … or/cbegin/

Dans l'exemple fourni au #4, cbegin est utilisé lorsque le besoin est une lecture et begin est utilisé lorsqu'il y a une modification

Hors ligne

#11 Le 04/07/2020, à 20:08

Nuliel

Re : for_each C++

Ok, merci NicoApi73

Hors ligne

#12 Le 05/07/2020, à 14:27

grigouille

Re : for_each C++

Si le container est const, il n'y a pas de différence entre cbegin et begin.


Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#13 Le 05/07/2020, à 14:48

grigouille

Re : for_each C++

chris7522 a écrit :

Pardonnez moi de passer un peu du coq a l'ane , mais je ne comprends pas ce code , lorsque j'enleve ma variable " un_booléen " de ma zone de capture , ca compile quand meme hmm

"un_booleen" et "un_entier" sont capturés de manière implicite car ils sont const, de type integral et initialisés par une expression constante. Si tu enlèves le const, ça ne compile plus.


Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#14 Le 05/07/2020, à 19:51

chris7522

Re : for_each C++

Ok merci a tous , c'est bien plus clair maintenant .

Hors ligne