Bonjour à tous je voulais simplement savoir si l'utilisation des variadic template était possible ou recréable sans utiliser la nouvelle norme c++11 ?
Merci
Bonjour à tous je voulais simplement savoir si l'utilisation des variadic template était possible ou recréable sans utiliser la nouvelle norme c++11 ?
Merci
Bonjour,
L'utilisation de template variadique n'est pas possible sans avoir un compilo supportant la nouvelle norme, en revanche il est très simple de les émuler en C++03.
Par exemple si l'on a le code suivant en C++11 :
Alors en C++03 il faudra écrire toutes les N surcharges correspondantes (avec N suffisamment grand pour que ça ne pose pas de problème en pratique)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 template <typename... Args> void foo(Args... args) { }
Comme tu le vois ça devient vite pénible
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 template <typename Arg1> void foo(Arg1 arg1) { } template <typename Arg1, typename Arg2> void foo(Arg1 arg1, Arg2 arg2) { } template <typename Arg1, typename Arg2, typename Arg3> void foo(Arg1 arg1, Arg2 arg2, Arg3 arg3) { } //etc
C'est effectivement très pénible ;D
Mais c'est ce que la nouvelle norme fait non ?
En tout cas j'hésite à installer un compilateur compatible c++11 j'ai lu quelque part que la compatibilité entre cette norme et la précédente n'était pas toujours évidente !
Est-ce vrai ? Si oui dans quels cas ?
Dans l'idée oui. Après je ne connais pas les détails d'implémentation d'un compilateur mais je suppose qu'il peut se permettre d'être un poil plus malin que de générer brutalement N surcharges, par exemple en instanciant uniquement les versions de la fonction qui sont réellement appelés dans le code.
Dans l'ensemble je trouve que le comité à fait un bon boulot pour éviter les cassures vraiment rédhibitoire. Et ils se sont aussi débrouillé dans la plupart des cas pour que les erreurs de compatibilité se manifestent à la compilation et pas à l’exécution.En tout cas j'hésite à installer un compilateur compatible c++11 j'ai lu quelque part que la compatibilité entre cette norme et la précédente n'était pas toujours évidente !
Est-ce vrai ? Si oui dans quels cas ?
Un bon résumé des cas problématiques ici :
http://blog.emmanueldeloget.com/inde...s-qui-changent
Quand on voit l'ampleur des changements apportés par C++11 je trouve que la liste ci-dessus est relativement réduite. Mais c'est vrai que sur les gros projets il y aura fatalement quelques heurts.
Il y a aussi moyen d'utiliser le préprocesseur pour écrire ces n versions différentes de templates (regarde http://www.boostpro.com/mplbook/preprocessor.html par exemple). C'est ce que fais couramment boost. Ou alors, on peut générer le code.
Je ne suis pas certain de comprendre ce que tu veux dire.
Des cas sont décrits dans la norme elle-même (annexe C2), mais je ne vois rien qui soit si complexe que ça a priori. Tu aurais plus d'infos ?
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.
Si la question est "est-ce que le compilateur instancie toutes les versions des variadic template à 1, 2, 3 etc paramètres, je dirais que ça dépend. Si tu utilises la récursion pour générer des fonctions (comme expliqué dans le tutoriel La meta-programmation en C++) forcement oui. Sinon, je pense pas, le compilateur instancie uniquement les versions qu'il a besoin (le contraire serait difficilement réaliste)
Bonsoir
1. Peut être que tu utilises déjà un compilateur qui supporte les variadic template ? (par exemple, gcc supporte depuis la version 4.3 en 2008, clang supporte depuis 2.9 et visual ne supporte pas du tout)
2. j'active par défaut le support du C++11 (pour gcc < 4.7 : -std=c++0x et gcc >= 4.7 : -std=c++11) depuis plusieurs années sans avoir rencontré de problème. Les problèmes soulignés par Emmanuel me semblent relativement anecdotiques
Je ne suis pas sûr que ça ait un intérêt. De toute façon, si tu écris du code C++11, alors il ne pourra être compilé que sur un compilateur qui comprends cette norme.
Les cassures ne sont pas si catastrophiques que ça. Il n'y en a qu'une qui peut poser problème (changement de sémantique d'un des constructeurs de std::vector<> ; le changement sémantique peut avoir un impact non négligeable sur le code, notamment si le type contenu manipule des pointeurs intelligents. Il s'agit probablement d'un défaut, et je pense que les implémentations vont le corriger avant qu'un errata soit validé par le comité de normalisation).
Mais globalement, il y a peu de chances que du code existant souffre réellement d'un passage à C++11.
Quand à faire des pseudo-variadic templates avec C++98, c'est effectivement vaguement possible (cf. plus haut) mais très, très contraignant. Qui plus est, le temps de compilation des programme tends à augmenter de manière significative lorsque le nombre d'arguments que tu proposes augmente. De plus, tu risque de heurter de plein fouet certaines limitations liés aux compilateurs - et notamment le nombre max de paramètres templates, qui peut ne pas être très élevé sur des compilateurs un peu trop ancien.
Maintenant, VC++ ne gère pas les variadic templates - donc selon l'architecture cible de tes programmes, tu peux être obligé d'utiliser la solution proposée ci-dessus. Et quand c'est nécessaire, la question de ce qu'il faut faire ne se pose plus
[FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.
Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.
Merci pour vos réponses
Je viens cependant de me poser une nouvelle question :
Imaginez une classe function templatee : <T,U,Args ...args>
Maintenant imaginez une classe composée, dérivant de function, ainsi templatée : <T,U,V,Args ... args>.
Cela ne pose pas de problèmes pour le moment. Sauf que voilà, cette classe composée est sensée pouvoir prendre en argument une instance de function, donc il faut préciser les paramètres template de cette function dans Composee : <T,U,V,Args ... argsComposee, Args ... argsFunctionArgument>
Oui mais voilà, si la composee accepte une instance de function en paramètre, elle accepte également une instance de composee, donc il faudrait pouvoir préciser tous les paramètres template de cette composee, et ainsi de suite : <T,U,V,Args ... argsComposee, Args ... argsComposee1, Args ... argsComposee2, [???] Args ...argsfunctionArgument>
Il faudrait donc pouvoir induire des templates "sur" variadiques (pour combler les points d'interrogation avec un nombre de template variable regroupé dans un "tableau">.
Est-ce possible ?
Il y a plus simple :
Et ensuite tu utilises des classes de traits si tu veux des détails.
Code : Sélectionner tout - Visualiser dans une fenêtre à part template<class... F>
Mais sinon :
Fonctionne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part tempalte<template<class...> class... F>
Je ne sais pas exactement où tu veux aller avec ton exemple de Compose, mais regardes sur C++Next, Nieber traite un exemple comme celui-ci dans un de ces articles.
Le fameux template de template variadique variadiques
C'est exactement ça
Pour ce qui est de l'article de nieber sur c++ next, pourrais-tu me donner le lien exact ? Je ne l'ai pas trouvé ^^ (ou un exemple un tout petit peu plus développé que le tien )
Merci pour le lien je vais regarder tout cela avec attention
Edit : lorsque je coche l'option -std=c++0x sous code blocks, l'option n'est pas reconnue au linkage, comment régler cela ?
Surement en mettant à jour MinGW, le portage de GCC et sa suite, pour Windows. Car j'imagine que la version accompagnant Code::Blocks commence à être vieille.
Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi
Ma page sur DVP
Mon Portfolio
Qui connaît l'erreur, connaît la solution.
J'ai posté un commentaire sur le billet du blog, mais ces problèmes de compatibilité ne sont pas forcément triviaux puisque pour l'exemple l'usage de std::set a été restreint dans le nouvelle norme.
Et pour répondre à LittleWhite, oui sur windows on a droit à g++4.5 avec C::B alors que la dernière version de mingw propose g++4.7 ce qui permet de faire quasi tout ce qu'on veut en C++11 (sauf tout ce qui se rapporte aux threads et aux regex).
C'est bizarre pourtant impossible de compiler avec l'option std -std=c++0x.
Comment savoir de quelle version de gcc je dispose ?
Sinon j'ai essayé de réinstaller mingw mais le problème c'est que j'obtiens un tas d'erreurs lors du linkage du programme.
Je ne vois pas vraiment ce qui cloche pourtant, et je pense que désinstaller mingw pour le réinstaller serait une perte de temps.
Que pensez-vous qu'il soit préférable de faire ?
Tu as installé quelle version ? Tu es sous quel OS avec quel IDE ?
Je suis sous code blocks sous windows 7 64 bits avec une version gcc indéterminée mais je pense suffisamment récente puisque c'est possible d'utiliser la norme c++11 d'après les messages précédents (gcc et mingw ont été installés en même temps que code blocks).
dans ce cas tu dois avoir g++4.5
Je te conseille de télécharger la version 4.7
pour cela va il faut dl mingw en cochant bien latest quand tu le vois dans l'installation. Je te conseille d'installer sous la racine. Puis tu vas dans c::b dans Settings->Compiler->ToolchainExecutable et dans Compiler's installation directory tu marques C:\MinGW si tu l'as mis sous la racine.
Tu cliques ok, tu redémarre c::b.
Puis voici le code qui va t'aider :
Il t'affichera la version qui a compilé ce code afin de vérifier si tu as bien installé comme il faut
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 std::cout << __GNUC__ << '.' << __GNUC_MINOR__ << '.' << __GNUC_PATCHLEVEL__ << std::endl;
Enfin l'option de compilation est -std=c++11 et non -std=c++0x (cette dernière te bloque aux fonctions de g++4.6). Il faut décocher dans les options de c::b et ajouter -std=c++11 dans other options
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager