Salut, j'ai vraiment du mal avec le c++17 moderne, parce que je trouve sa syntaxe assez complexe quand il s'agit de faire des opérations sur des types.
En fait je souhaiterais faire ceci. (Le code est un pseudo code que j'ai écrit ça sera peut être possible de le faire en c++2x mais, pour l'instant, ce pseudo code ne compilera tout simplement pas)
/*Définition d'une liste de types.*/
template <typename... Args>
struct List {
using type = Args...;
};
/* Ajoute un nouveau type à la liste de types.
List<A, L> = List<A, L>::type<A, xs...>*/
template <typename A, typename C = List> struct append {
template<typename seq, typename... xs>
using type = List<seq>::template type<A, C, xs...>;
};
template <typename pred, typename... Args>
struct copy_if {
//Déclaration d'un alias sur une constexpr.
using types = constexpr {
//On pourrait utiliser une boucle ici par exemple.
template <typename... C>
List copied;
for (unsigned int i = 0; i < sizeof...(Args); i++) {
//Spécialisation (if) on accède au parameter pack par un index, plutôt que de devoir utiliser un
std::tuple et des fonctions récursives qui alourdissent la syntaxe.
if (pred<args...[i]>::value) {
/*Par exemple is_placeholder<args...[i]> vaut soit vrai si le type est un placeholder, soit faux si il ne l'est pas*/
/*On insère le type, dans le paraméter pack, on pourrait imaginer que le c++ permette de faire ceci plutôt que de devoir mettre en œuvre des algorithmes très complexe qui alourdissent la syntaxe.*/
copied = append<args...[i], copied>::type;
}
}
/*On retourne l'alias sur le parameter pack, pas besoin d'utiliser une classe pour encapsuler le parameter pack ce qui est embêtant si on veut juste récupérer le parameter pack pour le passer à un autre template variadique et le manipuler avec une autre structure ça évite de devoir faire des structures imbriquées ce qui alourdi le code.*/
return copied::type;
}
Args... args;
};
template <typename... Args>
struct unique {
using types = constexpr {
template <typename... U>
List uniqueTypes;
for (unsigned int i = 0; i < sizeof...(Args); i++)
{
bool contains = false;
for (unsigned int j = 0; j < sizeof...(U) && !contains; j++) {
if (args...[i] == uniqueTypes::type...[j]) {
contains = true;
}
}
if (!contains) {
uniqueTypes=append<args...[i], uniqueTypes>::type;<br>
}
}
return uniqueTypes;
}
Args... args;
};
template<typename T>
struct Tmp {
using type = T;
};
/*Et on effectue la même chose pour le tri :
template<typename Pred, typename... Args>
struct sort {
unsigned type = constexpr {
for (unsigned int i = 0; i < sizeof...(Args)-1; i++)
{
for (unsigned int j = i+1; j < sizeof...(Args); j++) {
/*Inverse les types si le type j plus petit que le type i.*/
if (Pred<args...[j], args[i]...>::value) {
template<typename T>
Tmp<args...[i]> = args...[i];
args...[i] = args...[j];
args...[j] = Tmp<args...[i]>::type;
}
}
return args;
}
Args... args;
};
Je souhaiterai transformer ce code en un code compilable en c++17 mais je ne vois pas du tout comment m'y prendre.
Je ne vois pas comment ajouter la récursion (pour la boucle) avec en même temps, le if.
Je pensais à un truc du genre pour par exemple copy_if :
template <class List>
struct _append_if {
};
template <class A, class = std::enable_if<std::is_derived_from<std::true_type>::type>::type>
struct append_if {
template<class seq, class... xs>
using f = typename _append_if<seq>::template f<A, xs...>;
};
template <class A>
struct append_if {
template<class seq, class... xs>
using f = typename _append_if<seq>::template f<xs...>;
};
namespace emp {
template <class Cond, class L, class A, class... xs>
using append_if<A, Cond<A>> = typename _append_if<L>::template f<A, xs...>
}
template <class Cond, template<class...> class L>
struct copy_if {
using type = typename emp::append_if<Cond, L, ...>::f;
}
Je ne pense pas que ça soit bon et que ça va compiler mais c'est juste pour vous montrer ce que je veux faire.
Transformer ce template variadique ci <int, placeholders<1, double>, placeholders<0, std::string>,float, placeholders<0, std::string>> en ça : <placeholders<0, std::string>,placeholders<1,double>> mais c'est surtout pour m'entraîner à comprendre la méta programmation.
Je veux pas être rabat-joie, mais au vue de tes posts précédent, commence par écouter les intervenant (surtout ceux qui sont très expérimentés), et écrire quelque chose qui à défaut d'être optimal, est correcte et produit le résultat escompté. L'optimisation se fera plus tard (en fin de projet).
Premature optimization is the root of all evil (or at least most of it) in programming. (Donald Knuth)
Et, avant de t'adonner aux joies de la méta programmation, assure toi que le point précédent soit maîtrisé.
Il faut vraiment que tu apprennes à te fixer des objectifs et à déléguer, parce que là tu es en train de t'éparpiller de gauche à droite. Tu ne peux pas tout coder toi même. Tu es passé de créer un jeu à créer un moteur de jeu à créer un langage de script. C'est pas étonnant que tu avances aussi lentement en 10 ans. Personnellement je trouve que ce tu fais est du gâchis de motivation.
Malheureusement, pour déléguer, il faut que le projet soit clair, les objectives définis, que cela intéresse et motive les gens, etc.
Mais ce n'est pas le cas. Le GitHub montre très clairement des problèmes (fichiers qui n'ont rien a faire sur un repo, nommage non cohérent, pas d'issues/projets). Et une remarque qui revient très souvent dans toutes les discussions de OmbreNoire, c'est que les gens ne comprennent pas les questions posées et/ou quel est le but d'un code et/ou pourquoi une implémentation a été choisie et/ou le code est incompréhensible.
Même s'il arrive a trouver quelqu'un, je ne vois pas comment ça pourrait bien se passer. Ca sera très probablement une expérience désastreuse pour lui et il va en sortir avec la conclusion qu'il est préférable qu'il travaille seul.
-------------------------------
Mon conseil était de reprendre de 0, sur un projet simple. Au moins pour montrer qu'il sait gérer correctement un projet et qu'il sait faire du C++ propre.
Mais il a du mal à accepter qu'on remette en cause ses compétences, alors qu'il code depuis 10 ans.
Quand j'ai débarqué sur le forum, je me suis pris de sacrées tartes dans la gueule. Je me suis remis en question, ce qui a bien amélioré mes compétences (et j'ai encore probablement bcp à apprendre).
Ok finalement je pense que j'ai réussi, enfin tout du moins, le code compile, faudra vérifier si le type retourné est bon, faut encore que je vois comment faire ça, mais je vais continuer seul. (comme toujours)
template <class... A>
struct List {
};
template<class C>
struct unpack {
template<class seq, class... xs>
using f = typename List<seq>::template f<C, xs...>;
};
template<class A, class C>
struct push_front {
template<class seq, class... xs>
using f = typename List<seq>::template f<A, C, xs...>;
};
template<class A, class C, class Pred>
struct append_if {
template <typename seq>
requires std::derived_from<Pred, std::true_type>
List<push_front<A, C>> f() {
}
template <typename seq>
List<unpack<C>> f() {
}
using result = decltype(f());
};
template<class C, template <class> class Pred>
struct copy_if {
template<class seq, class... xs>
using f = typename List<seq>::template f<C, append_if<xs, C, Pred<xs>>...>;
};
int main(int argc, char* argv[])
{
List<copy_if< List<int, double, float,
placeholder<0, std::string>>, is_placeholder>> ulist;
return 0;
}
Je met longtemps parce que je suis plus motiver pour apprendre de nouvelles choses et les implémenter plutôt que de coder un jeux.
Mais je pense pas que créer un langage de script sera nécessaire si ce code fonctionne.
Certes, on est très critique, ce n'est pas pour rien. Nos conseilles ont pour but de te faire progresser.
Mais pour cela, il faut savoir ravaler sa fierté, prendre du recul. C'est difficile, c'est humiliant, mais le bénéfice que tu en tireras est largement supérieur aux désagrément engendrés.
J'ai fini par réussir comme quoi je dois continuer à croire en moi ce n'est pas de la fierté mais à chaque fois que je me suis laissé influencé par quelqu'un d'autre j'ai eu des problèmes.
A commencé par celui avec qui j'avais commencé le projet Sorrok il y a des années et qui a fini par se rebeller contre moi, il m'avait fait abandonné mon projet précédent pour passer de la 3D à la 2D iso et je croyais que j'allais avoir plus de chance en équipe, jusqu'à qu'il se rebelle contre les membres de l'équipe et ensuite contre moi.
> la librairie jnl ne compile pas sur tout les compilateurs
Cette librairie a perdu son combat contre msvc
Décris ce que tu veux faire au lieu d'écrire 150 lignes de pseudo code c++ que personne ne lit, ce serait plus simple
Des membres variadiques (Args... args;) ou des accès via un index (args...[i]) c'est faisable, mais il faut les packs dans une structure et appliquer les fonctions sur la structure ensuite.
Si tu veux juste t'entrainer, tu fais un type List, et t'appliques les transformations que tu veux dessus.
> > la librairie jnl ne compile pas sur tous les compilateurs
> Cette librairie a perdu son combat contre msvc
La première bataille seulement ; la seconde est une victoire ! Depuis que github-action a monté de version il y a 6 mois, il n'y a eu besoin que de 36 commits pour être compatible avec msvc-19.28.
Par contre, la macro de debug pour avoir des erreurs plus explicite est toujours activée, du coup c'est un peu plus lent qu'avec les autres compilateurs. Je prévois de séparer en 2 cette macro pour la prochaine version.
J'ai déjà eu un crash à cause d'un pointeur que j'alloue dynamiquement et que je stocke dans une std::Map ou un std::Vector, et qui change de valeur tout seul, juste en changeant l'endroit où je déclare le pointeur.
Hors un pointeur alloué dynamiquement ne devrait pas être détruit dans la std::Map ou le std:: Vector même si je le déclare dans le constructeur plutôt que dans la classe.
Ou alors c'est un bug de mingw.
Mais ça prend clairement moins de temps de réimplementer sa propre implémentation que de chercher un bug dans des milliers de lignes de codes.
Je te mets au défi d'écrire un code minimal qui reproduit ce crash et qui montre que le problème vient de map/vector et pas de ton code.
J'utilise map et vector depuis des dizaines d'années avec des pointeurs. Tout comme des milliers de devs C++. Tu penses que je vais conclure que c'est le milliers de devs qui se plantent ou toi ? Je te laisse reflechir a ca.
Mais ça prend clairement moins de temps de réimplementer sa propre implémentation que de chercher un bug dans des milliers de lignes de codes.
Il va vraiment falloir que tu arrêtes avec ton délire de bug dans l'implémentation de la bibliothèque standard du C++. S'il y en avait, il y aurait une tonne d'applications dans le monde qui planteraient tous les jours. Enfin c'est le cas, mais à cause de leur propre erreur dans leur code à eux.
Ni la libc++ (LLVM), libstdc++ (GCC) ou celle de Microsoft sont développés par un petit passionné le soir au travail sur un dépôt github perdu.
git is great because Linus did it, mercurial is better because he didn't.
J'avais mit un code source qui plantait sur mingw avec une std::map, je vais le tester sur g++ sous linux, je l'avais mit sur un autre sujet mais je vais le remettre dès que j'ai fini.
EDIT : bug de mingw, avec g++ sous linux ça ne plante pas.
Manifestement, tu n'as toujours pas compris. Montrer un code qui plante, ca ne prouve pas qu'il y a un bug dans map/vector, si tu ne localises pas la source du bug. En l'occurrence, vu ton code moisi, j'aurais tendance a penser que tu as fait n'importe quoi et que le bug ne vient pas de map/vector.
Et tu n'as a priori pas compris le mot "minimal". Parce qu'un code qui utilise les libs sfml, jnl et odfaeg, ce n'est pas du tout un code minimal.
MONTRE NOUS UN CODE MINIMAL QUI REPRODUIT LE BUG SUR MAP/VECTOR !
Manifestement, tu n'as toujours pas compris. Montrer un code qui plante, ca ne prouve pas qu'il y a un bug dans map/vector, si tu ne localises pas la source du bug. En l'occurrence, vu ton code moisi, j'aurais tendance a penser que tu as fait n'importe quoi et que le bug ne vient pas de map/vector.
Et tu n'as a priori pas compris le mot "minimal". Parce qu'un code qui utilise les libs sfml, jnl et odfaeg, ce n'est pas du tout un code minimal.
MONTRE NOUS UN CODE MINIMAL QUI REPRODUIT LE BUG SUR MAP/VECTOR !
- Edité par gbdivers il y a environ 3 heures
C'était un bug de mingw pas de la stl, avec g++ sous linux, ça ne plante pas.
> Tu veux que je fasse comment pour corriger un fichier avec plus de 1000 lignes de codes, non commenté et avec pleins d'erreurs en compilation ?
Ce que je trouve incroyable ici, est cette capacité à ne regarder qu'une chose: 1 fichier de 13k lignes. Alors qu'il suffit de lire le readme pour comprendre que ce fichier est une fusion de plus d'une 100 centaine de fichier avec tests et tout le tralala.
Mais c'est vrai qu'un readme d'une ligne et compliqué à lire...
Concernant ton code, il est faux. Il n'a pas fondamentalement changé depuis plusieurs semaines et contient toujours les mêmes conneries. Tu fais n'importe quoi avec memcpy, le code ne fonctionne et c'est normal.
Et comme d'habitude, ceci n'est absolument pas un code minimal.
- Edité par jo_link_noir 22 juillet 2021 à 13:52:33
Avec g++-10 je n'ai pas de soucis avec le memcpy, cette fonction est bête et ne fait que de copier les données se trouvant dans les void* d'un delegate à l'autre, je n'ai besoin de ne faire qu'une bêtes copie d'octets, rien d'autre, ce n'est pas le delegate qui se charge de cloner les objets qu'il contient.
Avec g++-10 je n'ai pas de soucis avec le memcpy, cette fonction est bête et ne fait que de copier les données se trouvant dans les void* d'un delegate à l'autre, je n'ai besoin de ne faire qu'une bêtes copie d'octets, rien d'autre, ce n'est pas le delegate qui se charge de cloner les objets qu'il contient.
S'il te plait quitte ce forum. Tu énerves tout le monde avec tes hypothèses infondées. On est plusieurs à te dire que tu as tort et tu penses que tu as toujours raison. Tes interventions ne servent à rien ici.
git is great because Linus did it, mercurial is better because he didn't.
× 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.
Eug
Discord NaN. Mon site.
Discord NaN. Mon site.
https://zestedesavoir.com/tutoriels/822/la-programmation-en-c-moderne/
Discord NaN. Mon site.
https://zestedesavoir.com/tutoriels/822/la-programmation-en-c-moderne/
Discord NaN. Mon site.
git is great because Linus did it, mercurial is better because he didn't.
Discord NaN. Mon site.
git is great because Linus did it, mercurial is better because he didn't.