Je dois être le seul a avoir participé, quelle tristesse
Le code n'est pas très intéressant en fait, je m'étais amusé avec les variadic templates et les lambdas un jour, et je me suis vite rendu compte que c'est une très mauvaise idée. Ca commence par gdb qui refuse de déboguer quoi que ce soit en segfaultant au chargement des symboles, et ça fini rapidement par faire exploser complètement les divers compilateurs.
oneshot, que je déconseille fortement de tester, à moins d'avoir genre 12Go de RAM de rab, et qui génère une erreur unique de 3-4Go (et on peut faire largement pire en augmentant le 11, quitte à avoir la RAM qui convient):
Code:
#define d template<typename...A> static void g(A...)
template<int N>struct f{d{f<N+1>::g([](A...,A...,A...,A...){});}};
template<>struct f<11>{d{[](A...){}();}};
void g(){f<0>::g();}
levenshtein, dans le même ordre de grandeur, et en trichant à mort pour le code qui est censé inverser le texte en input et en utilisant une macro pour tricher aussi tant qu'on y est sur le caractère unique à changer.
le fichier erroné:
Code:
#include<ios>
#define B A...
#define d template<typename...A>static void g(B)
template<int N>struct f{d{f<N+1>::g([](B,B,B,B){});}};template<>struct f<11>{d{[](B){}();}};
int main(){f<0>::g();system("(tr '\n' '#'|rev|tr '#' '\n')<test.dat>output.dat");}
le fichier correct:
Code:
#include<ios>
#define B A...
#define d template<typename...A>static void g(B)
template<int N>struct f{d{f<N+1>::g([](B,B,B,B){});}};template<>struct f<11>{d{[](){}();}};
int main(){f<0>::g();system("(tr '\n' '#'|rev|tr '#' '\n')<test.dat>output.dat");}
precision, qui donne π Mo de message d'erreur.
Code:
#define d template<typename...A> static void g(A...)
template<int N>struct ff{d{ff<N+1>::g([](A...){},[](A...,A...,A...,A...){});}};
template<>struct ff<5>{d{[](A...,A...,A...,A...,unsigned,long){ }(g);}};//pi!
void g(){ff<0>::g();}
---------- Post added at 01h54 ---------- Previous post was at 01h44 ----------
Pour faire plus clair en fait la base c'est:
Une classe template dont le paramètre va servir à contrôler la profondeur de récursion.
Dans cette classe, une fonction statique template, dont le ou les paramètres sont des lambdas, et qui appellent les mêmes fonctions du niveau supérieur, en augmentant la signature des lambdas passées en arguments (le premier niveau appelle le second niveau avec des lambdas sans arguments, qui appelle le troisième niveau avec des lambdas prenant des lambdas, et ainsi de suite).
On peut multiplier le nombre d'arguments des lambdas ou le nombre de lambdas, je ne sais pas très précisément ce que ça donne niveau quantité d'erreur, j'ai surtout eu du mal à avoir le plus gros message d'erreur sans exploser la limite de RAM.
Code:
template<int N>
struct f {
template<typename...A>
static void g(A...) {
f<N+1>::g([](A...,A...,A...,A...){});
}
};
Ensuite un cas de base pour arrêter la récursion et introduire une erreur, qui sera affichée avec la signature de la fonction g, qui dépend donc de tous les appels récursifs précédents (donc gros). L'erreur c'est bêtement une lambda qui prend plein de paramètres, appelée sans rien (GCC va du coup explicitement indiquer quels paramètres il attendait, ce qui rend l'erreur encore plus grosse).
Code:
template<>
struct f<11> {
template<typename...A>
static void g(A...) {
[](A...){}();
}
};
Et une fonction bidon qui lance tout le bousin.
Code:
void g() {
f<0>::g();
}
Après le reste c'est du tweak pour faire rentrer dans les contraintes et de la bidouille / chance pour avoir la bonne taille d'erreur pour pi.