IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Transport de template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    56
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 56
    Par défaut Transport de template
    Bonjour à tous.

    Voilà, j'ai un petit soucis avec mes templates qui me pose de sacrée problèmes. Je voudrais pouvoir transporter de façon "générique" une liste de template differents.

    Exemple :
    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
    17
    // Une classe template
    template<typename T> class Test
    {
    public:
    	T variable ;
    	...
    };
     
    // Et plus loin
    Test list[2] ;
    list[0] = Test<int>() ;
    list[1] = Test<double>() ;
     
    for (i=0; i<1; i++)
    {
    	cout << list[i].variable << endl ;
    }
    Voilà, je voudrais un truc plus où moins dans le genre. Mais comme vous vous en doutez, le "Test list[2]" est impossible car il faut un type de template.
    Donc j'aurai voulu savoir comment rendre ce tableau generique. (Même si c'est un peu tordu, parce pour le moment, je vois pas comment m'en sortir)

    Merci à tous !

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Il te faut utiliser un typage dynamique.
    Le typage dynamique le plus utilisé en C++ est probablement le typage dynamique objet.

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    class Test_base
    {
    public:
        virtual std::ostream& display(std::ostream&) const = 0;
        virtual ~Test_base() {}
    };
     
    std::ostream& operator<<(std::ostream& os, const Test_base& t)
    {
        return t.display(os);
    }
     
    template<typename T>
    class Test : public Test_base
    {
    public:
        T variable;
     
        std::ostream& display(std::ostream& os) const
        {
            return os << variable;
        }
    };
     
    Test_base* list[2] ;
    list[0] = new Test<int>() ;
    list[1] = new Test<double>() ;
     
    for (i=0; i<2; i++)
    {
        cout << *list[i] << endl ;
    }
     
    for(i=0; i<2; i++)
        delete list[i];

  3. #3
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Il te faut utiliser un typage dynamique.
    Le typage dynamique le plus utilisé en C++ est probablement le typage dynamique objet.
    Qu'es qui existe à part le typage dynamique objet?

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Le variant et le duck typing.

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Le variant et le duck typing.
    Comment tu fais tu duck typing dynamique en C++?

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Ce n'est pas vraiment possible, il faudrait avoir des template virtuals ou similaire pour ça.
    On peut néanmoins se débrouiller si on se limite à une liste pré-déterminée de types, et qu'on dispose d'introspection.

    Voici un petit truc que j'avais fait par exemple
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    #include <iostream>
    #include <string>
    #include <stdexcept>
     
    #include <boost/mpl/map.hpp>
    #include <boost/mpl/vector.hpp>
    #include <boost/mpl/vector_c.hpp>
     
    #include <boost/mpl/at.hpp>
    #include <boost/mpl/has_key.hpp>
    #include <boost/mpl/front.hpp>
     
    #include <boost/mpl/and.hpp>
    #include <boost/mpl/equal.hpp>
    #include <boost/mpl/find_if.hpp>
     
    #include <boost/type_traits.hpp>
    #include <boost/utility/enable_if.hpp>
    #include <boost/variant.hpp>
     
    template<typename T>
    struct reflection
    {
    };
     
    template<typename T, typename Name, typename Args>
    struct has_member
    {
    	typedef typename boost::mpl::eval_if<
    		boost::mpl::has_key<
    			typename reflection<T>::type,
    			Name
    		>,
    		boost::mpl::find_if<
    			typename boost::mpl::at<
    				typename reflection<T>::type,
    				Name
    			>::type,
     
    			boost::mpl::bind<	
    				boost::mpl::quote3<boost::mpl::equal>,
     
    				boost::mpl::bind<
    					boost::mpl::quote1<boost::mpl::second>,
    					boost::mpl::_1
    				>,
    				Args,
     
    				boost::is_convertible<
    					boost::mpl::_1,
    					boost::mpl::_2
    				>
    			>
    		>,
    		boost::mpl::void_
    	>::type iter;
     
    	static const bool value = 
    		boost::mpl::eval_if<
    			boost::mpl::not_<
    				boost::is_same<
    					iter,
    					boost::mpl::void_
    				>
    			>,
    			boost::mpl::not_<
    				boost::is_same<
    					iter,
    					typename boost::mpl::end<
    						typename boost::mpl::at<
    							typename reflection<T>::type,
    							Name
    						>::type
    					>::type
    				>
    			>,
    			boost::mpl::false_
    		>::type::value;
     
    	typedef bool value_type;
    	typedef has_member<T, Name, Args> type;
     
    	typedef typename boost::mpl::eval_if<
    		boost::mpl::bool_<value>,
    		boost::mpl::first<
    			typename boost::mpl::deref<iter>::type
    		>,
    		boost::mpl::void_
    	>::type return_type;
    };
     
    template<>
    struct reflection<std::string>
    {
    	typedef boost::mpl::map<
    		boost::mpl::pair<
    			boost::mpl::vector_c<char, 'c', '_', 's', 't', 'r'>,
    			boost::mpl::vector<
    				boost::mpl::pair<
    					const char*,
    					boost::mpl::vector<>
    				>
    			>
    		>
    	> type;
    };
     
    template<>
    struct reflection<int>
    {
    	typedef boost::mpl::map<
    	> type;
    };
     
    typedef boost::variant<int, std::string> variant;
     
    class visitor : public boost::static_visitor<variant>
    {
    public:
    	template<typename T>
    	typename boost::enable_if<
    		has_member<T, boost::mpl::vector_c<char, 'c', '_', 's', 't', 'r'>, boost::mpl::vector<> >,
    		variant
    	>::type
    	operator()(T& t) const
        {
            std::cout << t.c_str() << std::endl;
        }
     
    	template<typename T>
    	typename boost::disable_if<
    		has_member<T, boost::mpl::vector_c<char, 'c', '_', 's', 't', 'r'>, boost::mpl::vector<> >,
    		variant
    	>::type
    	operator()(T& t) const
    	{
    		throw std::runtime_error("type " + std::string(typeid(T).name()) + " doesn't have c_str()");
    	}
    };
     
    int main()
    {
        variant u1 = std::string("hello");
        variant u2 = 4;
     
        boost::apply_visitor( visitor(), u1 ); // same as u1.c_str()
        boost::apply_visitor( visitor(), u2 ); // same as u2.c_str()
    }
    Le format d'introspection est pas terrible, il faudrait qu'on puisse appeler les fonctions membres à partir de leur nom (ce qui permettrait d'automatiser la création des foncteurs)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Templates] Quel système utilisez-vous ? Pourquoi ?
    Par narmataru dans le forum Bibliothèques et frameworks
    Réponses: 270
    Dernier message: 26/03/2011, 00h15
  2. Template XHTML
    Par Sylvain James dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 16/06/2003, 21h45
  3. appliquer plusieurs templates
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 04/04/2003, 16h26
  4. template match="node() mais pas text()"
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/03/2003, 10h52
  5. [XSLT] template
    Par demo dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 09/09/2002, 11h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo