wrote:Le problème avec cette méthode, c'est que tu ne pas retourner un
objet du type du template par exemple (les fonctions de PipoBase ne
peuvent pas savoir qu'on va dériver en template...).
D'ailleurs, si quelqu'un a une solution pour palier à ce dernier
problème, je suis preneur :-)
Je crois que boost::any pourrait faire l'affaire. Mais je me
poserais des questions : pourquoi ? Qu'est-ce qu'on va réelement
faire avec pipo ?
J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float, types
persos...), et duquel on pourrait avoir la valeur. Comme un type
intégral en fait, mais encapsulé pour pouvoir traiter un vector de
tels objets et les manipuler chacun pareil.
Voilà un code qui résume un peu (en raccourci) :
class UVarBase
{
public:
virtual xxx GetValue () const = 0;
};
template <class T>
class UVar
{
public:
typedef const_ref_type const T&;
virtual xxx GetValue () const = 0;
// je voudrais :
virtual const T& GetValue () const = 0;
};
Bon, je n'ai pas mis les opérateurs et les setteurs... Mais l'idée y
est. Dans la classe de base, on ne peut pas connaître le type template
final. Du coup, la fonction GetValue ne peut pas renvoyer le bon type
directement. Alors moi j'avais fait renvoyer un void*, que je
recastais ensuite en faisant confiance au programmeur qui appelait la
fonction :
template <class T>
typename UVar<T>::const_ref_type UVarValue (const UVar<T>* pUVar)
{
return *(reinterpret_cast<UVar<T>::const_pointer_type>(pUVar->GetValue()));
}
kanze@gabi-soft.fr wrote:
Le problème avec cette méthode, c'est que tu ne pas retourner un
objet du type du template par exemple (les fonctions de PipoBase ne
peuvent pas savoir qu'on va dériver en template...).
D'ailleurs, si quelqu'un a une solution pour palier à ce dernier
problème, je suis preneur :-)
Je crois que boost::any pourrait faire l'affaire. Mais je me
poserais des questions : pourquoi ? Qu'est-ce qu'on va réelement
faire avec pipo ?
J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float, types
persos...), et duquel on pourrait avoir la valeur. Comme un type
intégral en fait, mais encapsulé pour pouvoir traiter un vector de
tels objets et les manipuler chacun pareil.
Voilà un code qui résume un peu (en raccourci) :
class UVarBase
{
public:
virtual xxx GetValue () const = 0;
};
template <class T>
class UVar
{
public:
typedef const_ref_type const T&;
virtual xxx GetValue () const = 0;
// je voudrais :
virtual const T& GetValue () const = 0;
};
Bon, je n'ai pas mis les opérateurs et les setteurs... Mais l'idée y
est. Dans la classe de base, on ne peut pas connaître le type template
final. Du coup, la fonction GetValue ne peut pas renvoyer le bon type
directement. Alors moi j'avais fait renvoyer un void*, que je
recastais ensuite en faisant confiance au programmeur qui appelait la
fonction :
template <class T>
typename UVar<T>::const_ref_type UVarValue (const UVar<T>* pUVar)
{
return *(reinterpret_cast<UVar<T>::const_pointer_type>(pUVar->GetValue()));
}
wrote:Le problème avec cette méthode, c'est que tu ne pas retourner un
objet du type du template par exemple (les fonctions de PipoBase ne
peuvent pas savoir qu'on va dériver en template...).
D'ailleurs, si quelqu'un a une solution pour palier à ce dernier
problème, je suis preneur :-)
Je crois que boost::any pourrait faire l'affaire. Mais je me
poserais des questions : pourquoi ? Qu'est-ce qu'on va réelement
faire avec pipo ?
J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float, types
persos...), et duquel on pourrait avoir la valeur. Comme un type
intégral en fait, mais encapsulé pour pouvoir traiter un vector de
tels objets et les manipuler chacun pareil.
Voilà un code qui résume un peu (en raccourci) :
class UVarBase
{
public:
virtual xxx GetValue () const = 0;
};
template <class T>
class UVar
{
public:
typedef const_ref_type const T&;
virtual xxx GetValue () const = 0;
// je voudrais :
virtual const T& GetValue () const = 0;
};
Bon, je n'ai pas mis les opérateurs et les setteurs... Mais l'idée y
est. Dans la classe de base, on ne peut pas connaître le type template
final. Du coup, la fonction GetValue ne peut pas renvoyer le bon type
directement. Alors moi j'avais fait renvoyer un void*, que je
recastais ensuite en faisant confiance au programmeur qui appelait la
fonction :
template <class T>
typename UVar<T>::const_ref_type UVarValue (const UVar<T>* pUVar)
{
return *(reinterpret_cast<UVar<T>::const_pointer_type>(pUVar->GetValue()));
}
(en vérité, c'était pour un autre usage : une suite d'options dans un
de mes programmes... Mais bon).
Peut-être existe-t-il un meilleur idiôme pour faire ce que je voulais...
Mais ça me permettait d'avoir un vector<UVarBase*> et de pouvoir gérer
toutes les options facilement (à partir de leur nom). Mais ça impose
de faire très attention au paramètre template donne à UVarValue
(UVarBase*).
(en vérité, c'était pour un autre usage : une suite d'options dans un
de mes programmes... Mais bon).
Peut-être existe-t-il un meilleur idiôme pour faire ce que je voulais...
Mais ça me permettait d'avoir un vector<UVarBase*> et de pouvoir gérer
toutes les options facilement (à partir de leur nom). Mais ça impose
de faire très attention au paramètre template donne à UVarValue
(UVarBase*).
(en vérité, c'était pour un autre usage : une suite d'options dans un
de mes programmes... Mais bon).
Peut-être existe-t-il un meilleur idiôme pour faire ce que je voulais...
Mais ça me permettait d'avoir un vector<UVarBase*> et de pouvoir gérer
toutes les options facilement (à partir de leur nom). Mais ça impose
de faire très attention au paramètre template donne à UVarValue
(UVarBase*).
"Michaël Monerau" wrote in message
news:<yqXdb.181419$...(en vérité, c'était pour un autre usage : une suite d'options dans un
de mes programmes... Mais bon).
Peut-être existe-t-il un meilleur idiôme pour faire ce que je
voulais...
Mais ça me permettait d'avoir un vector<UVarBase*> et de pouvoir
gérer toutes les options facilement (à partir de leur nom). Mais ça
impose
de faire très attention au paramètre template donne à UVarValue
(UVarBase*).
C'est alors pour gérer les options. Tu pourrais régarder ce que j'ai
fait dans GB_CommandLine/GB_Option à ma site, par exemple. Mais la
principe est simple : il y a bel et bien une classe de base
(GB_Option), qui a une fonction virtuelle pure « set ». Mais cette
fonction ne prend pas de paramètres -- la classe de base GB_Option
collabore avec GB_CommandLine pour pouvoir fournir les chaînes de la
ligne de commande, si l'option a besoin d'un paramètre. Et il n'y a
pas de getter du tout, au niveau de la classe de base --
l'utilisateur d'une option donnée doit bien savoir le type de
l'option, et avoir accès à la classe dérivée.
Note aussi que certaines options n'ont pas de valeur dans le sens
classique, mais provoque une action, qui peut changer l'état de
plusieurs variables.
"Michaël Monerau" <cort@meloo.com> wrote in message
news:<yqXdb.181419$hd6.2305778@news.chello.at>...
(en vérité, c'était pour un autre usage : une suite d'options dans un
de mes programmes... Mais bon).
Peut-être existe-t-il un meilleur idiôme pour faire ce que je
voulais...
Mais ça me permettait d'avoir un vector<UVarBase*> et de pouvoir
gérer toutes les options facilement (à partir de leur nom). Mais ça
impose
de faire très attention au paramètre template donne à UVarValue
(UVarBase*).
C'est alors pour gérer les options. Tu pourrais régarder ce que j'ai
fait dans GB_CommandLine/GB_Option à ma site, par exemple. Mais la
principe est simple : il y a bel et bien une classe de base
(GB_Option), qui a une fonction virtuelle pure « set ». Mais cette
fonction ne prend pas de paramètres -- la classe de base GB_Option
collabore avec GB_CommandLine pour pouvoir fournir les chaînes de la
ligne de commande, si l'option a besoin d'un paramètre. Et il n'y a
pas de getter du tout, au niveau de la classe de base --
l'utilisateur d'une option donnée doit bien savoir le type de
l'option, et avoir accès à la classe dérivée.
Note aussi que certaines options n'ont pas de valeur dans le sens
classique, mais provoque une action, qui peut changer l'état de
plusieurs variables.
"Michaël Monerau" wrote in message
news:<yqXdb.181419$...(en vérité, c'était pour un autre usage : une suite d'options dans un
de mes programmes... Mais bon).
Peut-être existe-t-il un meilleur idiôme pour faire ce que je
voulais...
Mais ça me permettait d'avoir un vector<UVarBase*> et de pouvoir
gérer toutes les options facilement (à partir de leur nom). Mais ça
impose
de faire très attention au paramètre template donne à UVarValue
(UVarBase*).
C'est alors pour gérer les options. Tu pourrais régarder ce que j'ai
fait dans GB_CommandLine/GB_Option à ma site, par exemple. Mais la
principe est simple : il y a bel et bien une classe de base
(GB_Option), qui a une fonction virtuelle pure « set ». Mais cette
fonction ne prend pas de paramètres -- la classe de base GB_Option
collabore avec GB_CommandLine pour pouvoir fournir les chaînes de la
ligne de commande, si l'option a besoin d'un paramètre. Et il n'y a
pas de getter du tout, au niveau de la classe de base --
l'utilisateur d'une option donnée doit bien savoir le type de
l'option, et avoir accès à la classe dérivée.
Note aussi que certaines options n'ont pas de valeur dans le sens
classique, mais provoque une action, qui peut changer l'état de
plusieurs variables.
J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float, types
persos...), et duquel on pourrait avoir la valeur. Comme un type
intégral en fait, mais encapsulé pour pouvoir traiter un vector de
tels objets et les manipuler chacun pareil.
C'est difficile à dire avec si peu d'informations, mais a priori, j'ai
l'impression que tu cherches à utiliser l'héritage quand c'est les
templates qui conviennent.
Mais je ne vois toujours pas l'intérêt de UVarBase et des fonctions
virtuelles. Quoique tu fasses, il faut que l'utilisateur sache le type
réel. Alors, le template suffit ; il n'y a pas besoin de la base et de
l'héritage.
Bon, je n'ai pas mis les opérateurs et les setteurs... Mais l'idée y
est. Dans la classe de base, on ne peut pas connaître le type
template final. Du coup, la fonction GetValue ne peut pas renvoyer
le bon type directement. Alors moi j'avais fait renvoyer un void*,
que je
recastais ensuite en faisant confiance au programmeur qui appelait la
fonction :
template <class T>
typename UVar<T>::const_ref_type UVarValue (const UVar<T>* pUVar)
{
return
*(reinterpret_cast<UVar<T>::const_pointer_type>(pUVar->GetValue()));
}
Et si l'utilisateur se trompait du type ?
Il y a de très rares cas où une telle construction se justifie. Dans
de tels cas, je me rebattrais sur boost::any.
J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float, types
persos...), et duquel on pourrait avoir la valeur. Comme un type
intégral en fait, mais encapsulé pour pouvoir traiter un vector de
tels objets et les manipuler chacun pareil.
C'est difficile à dire avec si peu d'informations, mais a priori, j'ai
l'impression que tu cherches à utiliser l'héritage quand c'est les
templates qui conviennent.
Mais je ne vois toujours pas l'intérêt de UVarBase et des fonctions
virtuelles. Quoique tu fasses, il faut que l'utilisateur sache le type
réel. Alors, le template suffit ; il n'y a pas besoin de la base et de
l'héritage.
Bon, je n'ai pas mis les opérateurs et les setteurs... Mais l'idée y
est. Dans la classe de base, on ne peut pas connaître le type
template final. Du coup, la fonction GetValue ne peut pas renvoyer
le bon type directement. Alors moi j'avais fait renvoyer un void*,
que je
recastais ensuite en faisant confiance au programmeur qui appelait la
fonction :
template <class T>
typename UVar<T>::const_ref_type UVarValue (const UVar<T>* pUVar)
{
return
*(reinterpret_cast<UVar<T>::const_pointer_type>(pUVar->GetValue()));
}
Et si l'utilisateur se trompait du type ?
Il y a de très rares cas où une telle construction se justifie. Dans
de tels cas, je me rebattrais sur boost::any.
J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float, types
persos...), et duquel on pourrait avoir la valeur. Comme un type
intégral en fait, mais encapsulé pour pouvoir traiter un vector de
tels objets et les manipuler chacun pareil.
C'est difficile à dire avec si peu d'informations, mais a priori, j'ai
l'impression que tu cherches à utiliser l'héritage quand c'est les
templates qui conviennent.
Mais je ne vois toujours pas l'intérêt de UVarBase et des fonctions
virtuelles. Quoique tu fasses, il faut que l'utilisateur sache le type
réel. Alors, le template suffit ; il n'y a pas besoin de la base et de
l'héritage.
Bon, je n'ai pas mis les opérateurs et les setteurs... Mais l'idée y
est. Dans la classe de base, on ne peut pas connaître le type
template final. Du coup, la fonction GetValue ne peut pas renvoyer
le bon type directement. Alors moi j'avais fait renvoyer un void*,
que je
recastais ensuite en faisant confiance au programmeur qui appelait la
fonction :
template <class T>
typename UVar<T>::const_ref_type UVarValue (const UVar<T>* pUVar)
{
return
*(reinterpret_cast<UVar<T>::const_pointer_type>(pUVar->GetValue()));
}
Et si l'utilisateur se trompait du type ?
Il y a de très rares cas où une telle construction se justifie. Dans
de tels cas, je me rebattrais sur boost::any.
Je vais regarder tes classe GB_Option et GB_CommandLine, je
comprendrai sûrement mieux de quoi tu parles. Mais je ne saisis pas
comment une option sans getteur peut être utile. Comment récupérer sa
valeur ? (par exemple, l'option -o de gcc, tu dois bien recueillir le
chemin qu'il y a derrière...)
Je vais regarder tes classe GB_Option et GB_CommandLine, je
comprendrai sûrement mieux de quoi tu parles. Mais je ne saisis pas
comment une option sans getteur peut être utile. Comment récupérer sa
valeur ? (par exemple, l'option -o de gcc, tu dois bien recueillir le
chemin qu'il y a derrière...)
Je vais regarder tes classe GB_Option et GB_CommandLine, je
comprendrai sûrement mieux de quoi tu parles. Mais je ne saisis pas
comment une option sans getteur peut être utile. Comment récupérer sa
valeur ? (par exemple, l'option -o de gcc, tu dois bien recueillir le
chemin qu'il y a derrière...)
wrote:J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float,
types persos...), et duquel on pourrait avoir la valeur. Comme un
type intégral en fait, mais encapsulé pour pouvoir traiter un
vector de tels objets et les manipuler chacun pareil.
C'est difficile à dire avec si peu d'informations, mais a priori,
j'ai l'impression que tu cherches à utiliser l'héritage quand c'est
les templates qui conviennent.
L'héritage est utile dans mon cas. En effet, je veux pouvoir stocker
toutes les options dans le même vector<>. Comme ça, l'utilisateur tape
à la console "option3 = 45". Je cherche dans mon vector<> de base*
(par un GetName() que base contient en virtuelle pure) le nom Option3.
Ensuite, j'aimerais faire un 'set (45)'. Pour l'instant, pour le
setteurs et le getteur, je passe par du void* casté dans le type que
le programmeur donne... Ce qui n'est pas très safe.
Pareil pour le get. S'il tape "option3" à la console, je veux que la
valeur s'affiche. Ici, 'print()' pourrait être appelée, mais si je
veux *vraiment* la valeur, dans un int, le seul moyen que je vois
serait de passer par ma fonction UVarValue.
kanze@gabi-soft.fr wrote:
J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float,
types persos...), et duquel on pourrait avoir la valeur. Comme un
type intégral en fait, mais encapsulé pour pouvoir traiter un
vector de tels objets et les manipuler chacun pareil.
C'est difficile à dire avec si peu d'informations, mais a priori,
j'ai l'impression que tu cherches à utiliser l'héritage quand c'est
les templates qui conviennent.
L'héritage est utile dans mon cas. En effet, je veux pouvoir stocker
toutes les options dans le même vector<>. Comme ça, l'utilisateur tape
à la console "option3 = 45". Je cherche dans mon vector<> de base*
(par un GetName() que base contient en virtuelle pure) le nom Option3.
Ensuite, j'aimerais faire un 'set (45)'. Pour l'instant, pour le
setteurs et le getteur, je passe par du void* casté dans le type que
le programmeur donne... Ce qui n'est pas très safe.
Pareil pour le get. S'il tape "option3" à la console, je veux que la
valeur s'affiche. Ici, 'print()' pourrait être appelée, mais si je
veux *vraiment* la valeur, dans un int, le seul moyen que je vois
serait de passer par ma fonction UVarValue.
wrote:J'avais eu le pb avec un système que je voulais implémenter : je
voulais faire une variable d'un type que l'on veut (int, float,
types persos...), et duquel on pourrait avoir la valeur. Comme un
type intégral en fait, mais encapsulé pour pouvoir traiter un
vector de tels objets et les manipuler chacun pareil.
C'est difficile à dire avec si peu d'informations, mais a priori,
j'ai l'impression que tu cherches à utiliser l'héritage quand c'est
les templates qui conviennent.
L'héritage est utile dans mon cas. En effet, je veux pouvoir stocker
toutes les options dans le même vector<>. Comme ça, l'utilisateur tape
à la console "option3 = 45". Je cherche dans mon vector<> de base*
(par un GetName() que base contient en virtuelle pure) le nom Option3.
Ensuite, j'aimerais faire un 'set (45)'. Pour l'instant, pour le
setteurs et le getteur, je passe par du void* casté dans le type que
le programmeur donne... Ce qui n'est pas très safe.
Pareil pour le get. S'il tape "option3" à la console, je veux que la
valeur s'affiche. Ici, 'print()' pourrait être appelée, mais si je
veux *vraiment* la valeur, dans un int, le seul moyen que je vois
serait de passer par ma fonction UVarValue.
"Michaël Monerau" wrote in message
news:<XAgeb.200032$...Je vais regarder tes classe GB_Option et GB_CommandLine, je
comprendrai sûrement mieux de quoi tu parles. Mais je ne saisis pas
comment une option sans getteur peut être utile. Comment récupérer sa
valeur ? (par exemple, l'option -o de gcc, tu dois bien recueillir le
chemin qu'il y a derrière...)
"Michaël Monerau" <cort@meloo.com> wrote in message
news:<XAgeb.200032$hd6.2579014@news.chello.at>...
Je vais regarder tes classe GB_Option et GB_CommandLine, je
comprendrai sûrement mieux de quoi tu parles. Mais je ne saisis pas
comment une option sans getteur peut être utile. Comment récupérer sa
valeur ? (par exemple, l'option -o de gcc, tu dois bien recueillir le
chemin qu'il y a derrière...)
"Michaël Monerau" wrote in message
news:<XAgeb.200032$...Je vais regarder tes classe GB_Option et GB_CommandLine, je
comprendrai sûrement mieux de quoi tu parles. Mais je ne saisis pas
comment une option sans getteur peut être utile. Comment récupérer sa
valeur ? (par exemple, l'option -o de gcc, tu dois bien recueillir le
chemin qu'il y a derrière...)