OVH Cloud OVH Cloud

type_info et operateur de copie

4 réponses
Avatar
Benoit Rousseau
Bonne année à tous,

Pour simuler le comportement de fonctions avec une classe, je voudrais
fixer le type de chacun des arguments et vérifier les types à l'execution :

class Function {
public:
void addArgType( type_info ); //ajoute un argument de type type_info
void exec( list<BaseType*>& args );
protected:
list<type_info> types;
};

le constructeur de copie de type_info est privé pour éviter une copie,
mais ca ne m'arrange pas puisque je ne peux pas l'ajouter à ma liste.
Je ne peux pas utiliser les templates comme suggéré par Alexandrescu
puisque la résolution des types se fait à l'execution du programme
(parser vers un arbre syntaxique (?)).

J'ai une "solution" en stockant des pointeurs de type_info, mais je ne
suis pas sûr que ce soit conforme (je pense que c'est bon pour gcc (?))

Des suggestions ?

Est ce qu'il est prévu d'implementer les operateurs < et > pour
type_info ? heritage et descendance ? Je sais qu'on peut le faire avec
des templates, mais ce serait peut être bien de l'avoir de façon
"simple", non ?

--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/

4 réponses

Avatar
Gabriel Dos Reis
James Kanze writes:

[...]

| |> J'ai une "solution" en stockant des pointeurs de type_info, mais je
| |> ne suis pas sûr que ce soit conforme (je pense que c'est bon pour
| |> gcc (?))
|
| Pourquoi est-ce qu'il ne serait pas conforme : « The result of a
| typeid expresion is an lvalue [on peut en prendre l'adresse] [...] The
| lifetime of the object referred to by the lvalue extends to the end of
| the program. [L'adresse ne peut pas devenir invalide par la suite.] »
|
| |> Des suggestions ?
|
| Des pointeurs type_info*. C'est ce qui est prévu par la norme.

Oui. Il faut faire attention au fait que deux pointeurs différents
peuvent en fait pointer vers le même type_info, i.e. on peut avoir

p != q and *p == *q

-- Gaby
Avatar
James Kanze
Benoit Rousseau writes:

|> Pour simuler le comportement de fonctions avec une classe, je
|> voudrais fixer le type de chacun des arguments et vérifier les
|> types à l'execution :

|> class Function {
|> public:
|> void addArgType( type_info ); //ajoute un argument de type type_info
|> void exec( list<BaseType*>& args );
|> protected:
|> list<type_info> types;
|> };

Je ne suis pas sûr ce que tu veux faire au juste, mais j'ai
l'impression que boost::any pourrait t'aider. J'y jeterais un coup
d'oeil, au cas où.

|> le constructeur de copie de type_info est privé pour éviter
|> une copie, mais ca ne m'arrange pas puisque je ne peux pas l'ajouter
|> à ma liste.

|> Je ne peux pas utiliser les templates comme suggéré par
|> Alexandrescu puisque la résolution des types se fait à
|> l'execution du programme (parser vers un arbre syntaxique (?)).

|> J'ai une "solution" en stockant des pointeurs de type_info, mais je
|> ne suis pas sûr que ce soit conforme (je pense que c'est bon pour
|> gcc (?))

Pourquoi est-ce qu'il ne serait pas conforme : « The result of a
typeid expresion is an lvalue [on peut en prendre l'adresse] [...] The
lifetime of the object referred to by the lvalue extends to the end of
the program. [L'adresse ne peut pas devenir invalide par la suite.] »

|> Des suggestions ?

Des pointeurs type_info*. C'est ce qui est prévu par la norme.

|> Est ce qu'il est prévu d'implementer les operateurs < et > pour
|> type_info ?

Voir std::type_info::before.

Ce qu'il te faut, en fait, c'est quelque chose du genre :

struct Less
{
bool operator()(
std::type_info const* a,
std::type_info const* b ) const
{
return a->before( *b ) ;
}
} ;

À vrai dire, je ne sais pas pourquoi il n'y a pas quelque chose du
genre déjà dans la norme, mais c'est assez facile à
implémenter.

|> heritage et descendance ?

Comment hériter d'un type que tu ne peux pas instantier ? À quoi
est-ce que ça servira. (En fait, la seule chose qui t'interdit
d'écrire :

class C : public std::type_info {} ;

c'est le fait que type_info n'a pas de constructeur accessible.)

|> Je sais qu'on peut le faire avec des templates, mais ce serait peut
|> être bien de l'avoir de façon "simple", non ?

Pour quoi faire ?

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
James Kanze
Gabriel Dos Reis writes:

|> James Kanze writes:

|> [...]

|> | |> J'ai une "solution" en stockant des pointeurs de type_info,
|> | |> mais je ne suis pas sûr que ce soit conforme (je pense que
|> | |> c'est bon pour gcc (?))

|> | Pourquoi est-ce qu'il ne serait pas conforme : « The result of
|> | a typeid expresion is an lvalue [on peut en prendre l'adresse]
|> | [...] The lifetime of the object referred to by the lvalue extends
|> | to the end of the program. [L'adresse ne peut pas devenir invalide
|> | par la suite.] »

|> | |> Des suggestions ?

|> | Des pointeurs type_info*. C'est ce qui est prévu par la norme.

|> Oui. Il faut faire attention au fait que deux pointeurs
|> différents peuvent en fait pointer vers le même type_info,
|> i.e. on peut avoir

|> p != q and *p == *q

Tout à fait. De même pour la comparaison pour inégalité, il
faut se baser sur p->before( *q ), et non p < q.

Le pire, c'est que si on se trompe, ça peut très bien fonctionner
la plupart du temps.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
Benoit Rousseau
James Kanze wrote:
Benoit Rousseau writes:

|> Pour simuler le comportement de fonctions avec une classe, je
|> voudrais fixer le type de chacun des arguments et vérifier les
|> types à l'execution :

|> class Function {
|> public:
|> void addArgType( type_info ); //ajoute un argument de type type_info
|> void exec( list<BaseType*>& args );
|> protected:
|> list<type_info> types;
|> };

Je ne suis pas sûr ce que tu veux faire au juste, mais j'ai
l'impression que boost::any pourrait t'aider. J'y jeterais un coup
d'oeil, au cas où.


Je ne maitrise pas encore boost... Mais j'ai déjà mon BaseType qui
marche bien depuis quelques temps, alors je ne vais pas changer pour
faire mes tests (Quoi que).

Je veux faire de la verification de type. Lorsque je déclare une
fonction dans un langage de script, je donne le type des arguments.
Alors au lieu de garder des strings, je préfére mémoriser le type
(type_info) puis vérifier au cours de l'appel de la fonction (ou
vérifier le type à l'interieur des expressions utilisant les arguments).

Pourquoi est-ce qu'il ne serait pas conforme : « The result of a
typeid expresion is an lvalue [on peut en prendre l'adresse] [...] The
lifetime of the object referred to by the lvalue extends to the end of
the program. [L'adresse ne peut pas devenir invalide par la suite.] »


C'etait la question

|> Je sais qu'on peut le faire avec des templates, mais ce serait peut
|> être bien de l'avoir de façon "simple", non ?

Pour quoi faire ?
La vérification de type par les templates (comme elle est expliquée dans

Modern Design) se fait à la compilation. C'est donc efficace pour les
biblio.
Pour un petit langage de script, je dois vérifier les types des
"fonctions" à l'execution et ca ne marche pas (A moins que je ne
transforme le script en C/C++ puis que je le passe au compilateur.



--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/