C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Utilisation d'un typedef d'un énuméré dans une classe templa

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Pascal Béthune
Guest





PostPosted: Fri Nov 19, 2004 9:54 pm    Post subject: Utilisation d'un typedef d'un énuméré dans une classe templa Reply with quote



Bonjour,


Soit le code suivant:


class MyValueTrait
{
public:
enum ValueEnum { A, B, C, D, END };
};

template < class ValueTrait >
class Collection
{
public:
typedef typename ValueTrait::ValueEnum ValueEnum;

int & operator[]( ValueEnum valueEnum )
{
// source simplifié pour le post
return value_;
}

int value_;
};

L'instantiation du template ne pose pas de problème:


int main()
{
Collection< MyValueTrait > collection;


L'utilisation de la méthode en utilisant l'énuméré de la classe
MyValueTrait ne pose pas de problème non plus:


collection[ MyValueTrait::A ] = 3;


Mais, si j'utilise l'énuméré de la classe template, ça ne fonctionne pas:


collection[ Collection< MyValueTrait >::A ] = 3; // ligne 37

return 0;
}


J'ai le message suivant (gcc 3.3.3 sur fedora core 2):


g++ -Wall -ansi -o extrait extrait.cpp
extrait.cpp: Dans function « int main() »:
extrait.cpp:37: error: `A' is not a member of type
`Collection<MyValueTrait>'


Pourquoi le typedef de la classe Collection ne me permet t-il pas
d'écrire cela ? Y a t-il un autre moyen de faire ? Est-ce un
bug/limitation de gcc ?


-- Pascal
Back to top
Fabien LE LEZ
Guest





PostPosted: Fri Nov 19, 2004 10:00 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote



On Fri, 19 Nov 2004 22:54:41 +0100, Pascal Béthune <nospam (AT) nospam (DOT) fr>:

Quote:
extrait.cpp:37: error: `A' is not a member of type
`Collection<MyValueTrait>'

Est-ce une erreur, d'après toi ?

La ligne "typedef typename ValueTrait::ValueEnum ValueEnum;" déclare
que "Collection<>" récupère le type "ValueEnum" de la classe
"ValueTrait", mais je ne suis pas sûr qu'elle parle des _valeurs_ A,
B, etc.


--
;-)

Back to top
Pascal Béthune
Guest





PostPosted: Fri Nov 19, 2004 10:07 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote



Re,

Fabien LE LEZ wrote:
Quote:
On Fri, 19 Nov 2004 22:54:41 +0100, Pascal Béthune <nospam (AT) nospam (DOT) fr>:


extrait.cpp:37: error: `A' is not a member of type
`Collection<MyValueTrait>'


Est-ce une erreur, d'après toi ?

La ligne "typedef typename ValueTrait::ValueEnum ValueEnum;" déclare
que "Collection<>" récupère le type "ValueEnum" de la classe
"ValueTrait", mais je ne suis pas sûr qu'elle parle des _valeurs_ A,
B, etc.



C'est bien ce que je constate. Comment pourrait t-on faire pour
"importer" les valeurs dans la classe template pour "masquer" à
l'utilisateur l'existance de la classe MyValueTrait ?

-- Pascal

Back to top
Pascal Béthune
Guest





PostPosted: Fri Nov 19, 2004 10:15 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

Pascal Béthune wrote:
Quote:

C'est bien ce que je constate. Comment pourrait t-on faire pour
"importer" les valeurs dans la classe template pour "masquer" à
l'utilisateur l'existance de la classe MyValueTrait ?

-- Pascal

Mettre dans la classe template


typedef ValueTrait Access;


et à l'utilisation:


collection[ Collection< MyValueTrait >::Access::A ] = 3;


Mais je ne trouve pas ça très élégant. Quelqu'un a une autre idée ?

-- Pascal

Back to top
Fabien LE LEZ
Guest





PostPosted: Fri Nov 19, 2004 10:41 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

On Fri, 19 Nov 2004 23:07:29 +0100, Pascal Béthune <nospam (AT) nospam (DOT) fr>:

Quote:
Comment pourrait t-on faire pour
"importer" les valeurs dans la classe template pour "masquer" à
l'utilisateur l'existance de la classe MyValueTrait ?

Déjà, il faudrait que tu expliques un peu plus clairement ta
problématique. Que représente exactement ton enum, et pourquoi est-il
dans le trait ?


--
;-)

Back to top
Pascal Béthune
Guest





PostPosted: Fri Nov 19, 2004 11:11 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

Fabien LE LEZ wrote:
Quote:
On Fri, 19 Nov 2004 23:07:29 +0100, Pascal Béthune <nospam (AT) nospam (DOT) fr>:


Comment pourrait t-on faire pour
"importer" les valeurs dans la classe template pour "masquer" à
l'utilisateur l'existance de la classe MyValueTrait ?


Déjà, il faudrait que tu expliques un peu plus clairement ta
problématique. Que représente exactement ton enum, et pourquoi est-il
dans le trait ?



J'ai une classe de base polymorphique Value.

La classe template Collection a pour but de faire une collection de
dérivées de Value.

Chaque Collection à un nombre fini de Value (d'ou l'énuméré).

A la construction de la Collection, je souhaite contruire le bon objet
dont la classe est dérivé de Value, d'où la classe MyValueTrait qui
contient une fonction statique instanciateValue( enuméré) qui retourne
un Value* et qui alloue le bon objet en fonction de la valeur de
l'énuméré. instanceValue est utilisé par le constructeur de Collection.

La classe template Collection prend alors comme parametre la classe
MyValueTrait qui contient l'énuméré et la fonction instanciateValue qui
dépend fortement de cet énuméré.

Ce méchanisme fonctionne bien, seulement lors se l'utilisation de la
classe template Collection (une fois instanciée grace a la classe
MyValueTrait) on doit "encore" avoir connaisssance de MyValueTrait alors
que Collection< MyValueTrait> pourrait suffire il me semble. c-à-d:

si dans un fichier include on à:

typedef Collection< MyValueTrait > MyCollection;

et dans un autre fichier:

MyCollection collection;

collection.value[ MyValueTrait::A ] = 8;
// fonctionne mais laisse apparaitre MyValueTrait
// alors que MyValueTrait n'apparait pas dans le fichier

collection.value[ MyCollection::A ] = 8;
// ne fonctionne pas :(

collection.value[ MyCollection::Access::A ] = 8;
// fonctionne mais me parait plus lourd


Voila le contexte.

-- Pascal

Back to top
Fabien LE LEZ
Guest





PostPosted: Fri Nov 19, 2004 11:29 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

On Fri, 19 Nov 2004 22:54:41 +0100, Pascal Béthune <nospam (AT) nospam (DOT) fr>:

Quote:
int & operator[]( ValueEnum valueEnum )
{
// source simplifié pour le post
return value_;

C'est bien joli de simplifier, mais là, c'est carrément incorrect : tu
renvoies une référence vers un objet qui ne survit pas à la fonction.


--
;-)

Back to top
Fabien LE LEZ
Guest





PostPosted: Fri Nov 19, 2004 11:39 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

On Sat, 20 Nov 2004 00:11:23 +0100, Pascal Béthune <nospam (AT) nospam (DOT) fr>:

Quote:
on doit "encore" avoir connaisssance de MyValueTrait

En fait, ça ne me paraît pas un problème. Si le enum est spécifique au
trait, pour connaître les valeurs, on doit lire la déclaration de la
classe de trait. Donc, continuer à en parler ne me paraît pas
scandaleux.

Au fait, j'ai l'impression que tu mélanges allègrement deux formes de
polymorphisme : l'héritage et les templates. Si tu souhaites utiliser
des templates, tu n'as pas forcément besoin de polymorphisme
d'héritage, et vice-versa.


--
;-)

Back to top
Pascal Béthune
Guest





PostPosted: Fri Nov 19, 2004 11:40 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

Fabien LE LEZ wrote:
Quote:
On Fri, 19 Nov 2004 22:54:41 +0100, Pascal Béthune <nospam (AT) nospam (DOT) fr>:


int & operator[]( ValueEnum valueEnum )
{
// source simplifié pour le post
return value_;


C'est bien joli de simplifier, mais là, c'est carrément incorrect : tu
renvoies une référence vers un objet qui ne survit pas à la fonction.



value_ est un attribut de la classe Collection. Donc le retour de
fonction survit à l'appel de fonction. (il ne s'agit pas d'une variable
locale).


-- Pascal

Back to top
Pascal Béthune
Guest





PostPosted: Fri Nov 19, 2004 11:53 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

Fabien LE LEZ wrote:
Quote:
On Sat, 20 Nov 2004 00:11:23 +0100, Pascal Béthune <nospam (AT) nospam (DOT) fr>:


on doit "encore" avoir connaisssance de MyValueTrait


En fait, ça ne me paraît pas un problème. Si le enum est spécifique au
trait, pour connaître les valeurs, on doit lire la déclaration de la
classe de trait. Donc, continuer à en parler ne me paraît pas
scandaleux.

Au fait, j'ai l'impression que tu mélanges allègrement deux formes de
polymorphisme : l'héritage et les templates. Si tu souhaites utiliser
des templates, tu n'as pas forcément besoin de polymorphisme
d'héritage, et vice-versa.



non, je ne confond pas les 2. C'est bien un template puisque je veux
autant de collection que de type énumérés possible.

le polymorphique est sur Value. a chaque valeur d'un énuméré, j'associe
un type dérivé de Value. Par exemple Vitesse, Altitude, Coordonnees ...

exemple:

class InputTrait
{
public:
enum ValueType { VITESSE, ALTITUDE, COORDONNEE, END };

static Value * instanciateValue( ValueType valueType )
{
Value * value;
switch( valueType ) {
case VITESSE : value = new Vitesse ; break;
case ALTITUDE : value = new Altitude ; break;
case COORDONNEE: value = new Coordonnee; break;
default: assert( "XXXXX" ); }
return value;
}
};


template< class ValueTrait >
class Collection
{
Collection()
{
for( cpt = 0; ValueTrait::END; ++cpt )
{
values_[ cpt ] = ValueTrait::instanciateValue( cpt );
}
}

Value * values_[ ValueTrait::END ];
};

typedef Collection< InputTrait > InputCollection;


code non testé mais qui donne un aperçu du méchanisme.

-- Pascal

Back to top
Pascal Béthune
Guest





PostPosted: Sat Nov 20, 2004 12:08 am    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

Fabien LE LEZ wrote:

Quote:
on doit "encore" avoir connaisssance de MyValueTrait

En fait, ça ne me paraît pas un problème. Si le enum est spécifique au
trait, pour connaître les valeurs, on doit lire la déclaration de la
classe de trait. Donc, continuer à en parler ne me paraît pas
scandaleux.

Moi non plus, ça ne me parait pas scandaleux. C'est juste que je
souhaitais la "masquer" un peu vis à vis des utilisateurs de collection.
Peut être vais-je pouvoir remedier au problème en changeant le nommage
de la classe trait pour la rendre plus "présentable" aux utilisateurs de
collection.

l'orgine de mon post était plus la surprise concernant le comportement
de typdef qui importe le type énéuméré dans le scope de la classe
Collection sans amener les valeurs de cet énuméré.

-- Pascal

Back to top
Jean-Marc Bourguet
Guest





PostPosted: Sat Nov 20, 2004 10:28 am    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

Pascal Béthune <nospam (AT) nospam (DOT) fr> writes:

Quote:
Pourquoi le typedef de la classe Collection ne me permet t-il pas d'écrire
cela ?

Parce que typedef introduit un synonyme et ne fait rien
d'autre.

Quote:
Est-ce un bug/limitation de gcc ?

Non.

Quote:
Y a t-il un autre moyen de faire ?

L'objectif donc est que les noms déclarés dans MyValueTraits
soient disponibles de manière non qualifiée dans Collection?
C'est assez simple: faire hériter Collection de
MyValueTraits:

class Collection: public ValueTrait

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Back to top
Pascal Béthune
Guest





PostPosted: Sat Nov 20, 2004 12:01 pm    Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te Reply with quote

Jean-Marc Bourguet wrote:

Quote:
Y a t-il un autre moyen de faire ?


L'objectif donc est que les noms déclarés dans MyValueTraits
soient disponibles de manière non qualifiée dans Collection?
C'est assez simple: faire hériter Collection de
MyValueTraits:

class Collection: public ValueTrait

C'est LA solution à mon problème (j'étais focalisé sur une solution
"typedef" en oubliant d'autre façon de faire).

La classe template Collection fournit alors à ses utilisateurs le type
énuméré ainsi que ses valeurs, mais fournit "naturellement" la façon
d'instancier le "bon" objet grace à la fonction statique
instanciateValue() ce qui ouvre d'autre possibilités fort interessantes.

Merci. :)

-- Pascal

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.