template

template - C++ - Programmation

Marsh Posté le 06-02-2009 à 03:46:06    

Hi,
 
J'avais déjà vu que le mot clef template pouvait être utilisé ailleurs que devant le nom d'une classe ou le nom d'une fonction ou pour faire une instanciation explicite.. mais je m'en rappel plus lol.
Un peu comme avec le mot clef typename que l'on mets aussi devant un membre donné pour que le compilateur sache que c'est un type.
 
Quelqu'un voit ?
 
Merci.


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
Reply

Marsh Posté le 06-02-2009 à 03:46:06   

Reply

Marsh Posté le 06-02-2009 à 07:38:52    

appel d'une methode template d'un objet tempalte:
 
MonObjet<T> m;
m::templte foo<U>();
 

Reply

Marsh Posté le 06-02-2009 à 09:41:54    

Reply

Marsh Posté le 06-02-2009 à 13:37:53    

c'est ça merci bien


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
Reply

Marsh Posté le 06-02-2009 à 13:57:40    

mais dans ton exemple, si on supprime les  .template et ->template le code compile quand même  :??: , Y a des cas ou  
sans .template, la compilation passe pas il me semble


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
Reply

Marsh Posté le 06-02-2009 à 14:40:58    

frenchtoucco a écrit :

mais dans ton exemple, si on supprime les  .template et ->template le code compile quand même  :??: , Y a des cas ou
sans .template, la compilation passe pas il me semble

 

De memoire, il n'est autorise que quand il est obligatoire en C++03.  De memoire toujours, en C++0X on relachera un peu cette contrainte.

 

Il y a (eu?) des compilateurs n'implementant par la recherche de noms en deux temps qui ignoraient purement et simplement ces indications aux endroits ou elles etaient autorisees grammaticalement sans verifier qu'elle etait autorisee semantiquement.  Et chez eux, les virer compile toujours.

 

Exemple complet et compilable (mais plutot stupide) ou ce devrait etre obligatoire (ce l'est pour gcc 4.3.3 et pour comeau http://www.comeaucomputing.com/tryitout/)

 
Code :
  1. template <typename T>
  2. int f(T x)
  3. {
  4.    typename T::result r = x.template g<int>(42);
  5.    return r;
  6. }
  7. struct X
  8. {
  9.    typedef int result;
  10.    template <typename T> T g(T x) { return x; }
  11. };
  12. #include <iostream>
  13. #include <ostream>
  14. int main()
  15. {
  16.    X x;
  17.    std::cout << f(x) << '\n';
  18.    return 0;
  19. }



Message édité par Un Programmeur le 06-02-2009 à 14:41:35
Reply

Marsh Posté le 06-02-2009 à 15:00:55    

ok donc c'est juste sous visual 2008 où le comportement est différent,  il ne requière pas l'utilistion du .template


Message édité par frenchtoucco le 06-02-2009 à 15:04:24

---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
Reply

Marsh Posté le 08-02-2009 à 11:30:48    

pas seulement visual C++, il vaut mieux rester 100% standard même si ton compilo est + tolérant. Sur certains compilos, 'typename' devant 'T::result' est également optionnel, mais il vaut mieux le mettre qd même.
 
Sinon, template est aussi utilisé pour indiquer qu'un paramètre d'un template est un autre template, mais je n'en ai jamais vu d'utilisation concrète.
http://www.informit.com/articles/article.aspx?p=376878


Message édité par jesus_christ le 08-02-2009 à 11:32:07
Reply

Marsh Posté le 08-02-2009 à 12:01:45    

ca servait avant MPL pour emuler des meta-fonctions d'ordre supérieur.
Le protocole apply l'a rendu obsolete.
 
Sinon t'as toujours le vieux :
 

Code :
  1. template<template<class> class Cont, class T>
  2. struct make_container
  3. {
  4.   return Cont<T> type;
  5. };


Reply

Marsh Posté le 08-02-2009 à 12:13:56    

oui mais bon ça c'est l'exemple scolaire classique, qui est donné sous une autre forme dans le lien ci dessus, mais en pratique je ne vois pas trop d'utilité concrète pour cette fonctionnalité, même si j'apprécie qu'il l'aie fournie, "power to the compiler" :D

Reply

Marsh Posté le 08-02-2009 à 12:13:56   

Reply

Marsh Posté le 08-02-2009 à 12:33:24    

En gros ca servait avant qu'on ai un vrai systeme de meta-fonction polymorphique.
Le truc ci-dessus s'ecrit desormais :

 
Code :
  1. template<class Model,class T> make_container : mpl::apply<Model,T> {};
  2. typedef make_container< vector<_>, float>::type vector_of_float;
 

Depusi MPL, les template tempalte ne servent que dans quelques cas foireux.


Message édité par Joel F le 08-02-2009 à 12:34:30
Reply

Marsh Posté le 08-02-2009 à 12:36:51    

pas mal ce mpl::apply, je ne connaissais pas !
par contre le token _, bof, risque de conflit avec gettext...

Reply

Marsh Posté le 08-02-2009 à 12:43:01    

pardon :
 
typedef make_container< vector<mpl::_>,float>::type
 
_ et ses freres (_1,_2,_3,_4,_5 et _6) sont juste des lambda-placeholder

Reply

Marsh Posté le 08-02-2009 à 12:50:03    

ben _1, _2 ok je connaissais avec boost::bind, mais _, c'est une macro de gettext, surement + ancienne que boost::mpl, donc ça me fait peur :(

Reply

Marsh Posté le 08-02-2009 à 12:58:37    

jesus_christ a écrit :

ben _1, _2 ok je connaissais avec boost::bind, mais _, c'est une macro de gettext, surement + ancienne que boost::mpl, donc ça me fait peur :(


 
C'est une macro fonction, donc tant que c'est pas suivit par une parenthèse il n'y a pas clash.  
 
Mais c'est quand même jouer aux limites.

Reply

Marsh Posté le 08-02-2009 à 15:44:28    

ouais enfin v_v paye ta macro aussi :E
Pour info, j'utilsie le meme token pour simuler le : de matlab dans ma bibliothèque de calcul numérique, ca n'a jamais clashé avec quoi que ce soit :E

Reply

Marsh Posté le 08-02-2009 à 18:10:11    

Un Programmeur a écrit :


 
C'est une macro fonction, donc tant que c'est pas suivit par une parenthèse il n'y a pas clash.  
 
Mais c'est quand même jouer aux limites.


 

Code :
  1. #define int() 6
  2. int n;


 
Ca marche ça ? Et bien j'ai appris un truc, merci ! Je pensais que les macros étaient toutes remplacées par le préprocesseur, macro-fonction ou pas. Dans ce cas pas de conflit entre _() de gettext et mpl::_ de boost :).

Reply

Marsh Posté le 08-02-2009 à 18:56:55    

jesus_christ a écrit :


 

Code :
  1. #define int() 6
  2. int n;


 
Ca marche ça ?


 
Oui.   Il faut faire simplement attention à ne pas inclure des entêtes standards parce qu'alors on passe dans le comportement indéfini.
 
Et à ne pas avoir des collègues violents naturellement.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed