 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Pascal Béthune Guest
|
Posted: Fri Nov 19, 2004 9:54 pm Post subject: Utilisation d'un typedef d'un énuméré dans une classe templa |
|
|
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
|
Posted: Fri Nov 19, 2004 10:00 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Fri Nov 19, 2004 10:07 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Fri Nov 19, 2004 10:15 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Fri Nov 19, 2004 10:41 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Fri Nov 19, 2004 11:11 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Fri Nov 19, 2004 11:29 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Fri Nov 19, 2004 11:39 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Fri Nov 19, 2004 11:40 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Fri Nov 19, 2004 11:53 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Sat Nov 20, 2004 12:08 am Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Sat Nov 20, 2004 10:28 am Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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
|
Posted: Sat Nov 20, 2004 12:01 pm Post subject: Re: Utilisation d'un typedef d'un énuméré dans une classe te |
|
|
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 |
|
 |
|
|
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
|
|