J'avais le nez dans la doc quand je suis tombé par hasard sur les Fold Expression. Au premier abord, ce fût comme une rencontre avec un extra-terrestre, puis j'ai essayé de comprendre ce machin.
Donc d'après ce que j'ai pu comprendre pour le moment, ce serait du sucre syntaxique évitant du code superflu lors de l'utilisation de paramater pack permettant de se passer d'une surcharge de la fonction de traitement pour stopper la récursion ?
Du coup pour m'entraîner un peu, j'ai repris un bout de code que @koala m'avait sympatiquement fourni il y a quelques mois (FootprintCreator : trouvable ici) et j'ai donc essayé de le remodeler sous forme de fold expression ce qui donne :
Donc pour le moment j'ai fait quelques tests et pas de souci particulier. Mais est-ce que c'est quelque chose que l'on peut utiliser systématiquement sans problème lorsque l'on a affaire a du paramater pack ? Ou il y a certaines limites à prendre en compte ?
Je n'ai pas le souvenir d'avoir vu des limitations spécifiques avec les folding expressions.
(On est en train de préparer un article sur le C++17 sur ZdS. Je ferais probablement une review plus poussées des folds a ce moment là, mais rien pour le moment)
Je n'ai pas le souvenir d'avoir vu des limitations spécifiques avec les folding expressions.
D'acc.
gbdivers a écrit:
(On est en train de préparer un article sur le C++17 sur ZdS. Je ferais probablement une review plus poussées des folds a ce moment là, mais rien pour le moment)
Avant les folds il y a possibilité de déballer l'expression dans un tableau puis de l'ignorer. Si on veut faire une opération binaire comme le | de ton exemple, il fallait utiliser une variable intermédiaire. (voir mon article).
Par contre, les folds ne permettent pas d'arrêter un parcours. On travaille sur toutes les valeurs ou aucune. La seule chose qui s'apparente à un arrêt dans le parcours sont les opérateurs logiques && et ||. Ces opérateurs sont paresseux, càd que dans a || b, si a est vrai alors b n'est jamais exécuté. Avec les folds c'est pareil, mais l'écriture est plus tordue quand on veut réécrire une fonction récursive qui contient des if/else. Si on ne veut pas passer par une fonction intermédiaire, je n'ai pas trouvé mieux qu'une lambda qui retourne un booléen.
([]{
if (xs.foo()) {
// des trucs
return true;
}
// encore des trucs
return false;
}() || ...);
- Edité par jo_link_noir 24 octobre 2018 à 20:12:53
Avant les folds il y a possibilité de déballer l'expression dans un tableau puis de l'ignorer. Si on veut faire une opération binaire comme le | de ton exemple, il fallait utiliser une variable intermédiaire. (voir mon article).
Oula j'ai sursauté en voyant la macro, quelle bête étrange .
jo_link_noir a écrit:
Par contre, les folds ne permettent pas d'arrêter un parcours. On travaille sur toutes les valeurs ou aucune.
Ah yes d'accord.
jo_link_noir a écrit:
Avec les folds c'est pareil, mais l'écriture est plus tordue quand on veut réécrire une fonction récursive qui contient des if/else. Si on ne veut pas passer par une fonction intermédiaire, je n'ai pas trouvé mieux qu'une lambda qui retourne un booléen.
Avec les opérateurs && et || ? Pour le coup je ne suis pas sûr de comprendre, tu aurais un petit exemple sans lambda avec une fonction intermédiaire ?
Un truc souvent effectué avec un pointeur est par exemple de vérifier qu'il est valide pour appeler une fonction membre. Par exemple "if (p && p->check())". La seconde partie (i.e. "p->check()") ne sera pas exécuté si p est nul.
Avec un fold c'est pareil. Si j'ai un pack d'objet qui possède chacun une fonction advance() qui retourne un booléen, je peux faire "(xs.advance() && ... )" et dès qu'il y a un false en retour, le fold s'arrête.
struct A
{
bool advance()
{
if (i > 2) {
return false;
}
++i;
return true;
}
int i = 0;
};
template<class... Ts>
void foo(Ts& ...xs)
{
(xs.advance() && ...);
}
#include <iostream>
int main()
{
A a;
foo(a,a,a,a,a,a,a,a,a,a,a); // très pertinent
std::cout << a.i; // affiche 3
}
- Edité par jo_link_noir 25 octobre 2018 à 15:45:16
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
...
Discord NaN. Mon site.
...
...
...