Retour à l'accueil
Accueil Aide Rechercher Calendrier Identifiez-vous Inscrivez-vous
Bienvenue, Invité. Veuillez vous connecter ou vous inscrire.
Avez-vous perdu votre courriel d'activation?
24 Juin 2019 à 20:58

Connexion avec identifiant, mot de passe et durée de la session
Règlement | Grades du forum | L'équipe de modération | Album photo | Chat
Rechercher:     avancée
Forums Zelda Solarus  |  Jeux amateurs  |  Programmation  |  Topic: [C++] Template typedef 0 Membres et 1 Invité sur ce sujet.
Pages: [1] Imprimer
Auteur Sujet: [C++] Template typedef  (Lu 2187 fois)
Morwenn
Sheikah
*
Offline Offline

Messages: 3 266


And so what?


WWW Courriel
« le: 28 Avril 2012 à 21:14 »

J'ai beau m'être amélioré en C++ ces derniers temps, il reste certains qui continuent à me paraître impossible à résoudre de manière simple. J'ai notamment un cas épineux faisant intervenir des templates et des alias de noms de classes. Sans plus tarder, voici le problème :

Imaginons que j'aie le code suivant :
Code: [Select]
template<typename T>
class A
{
    // ...
};

template<>
class A<int>
{
    // ...
};

template<typename T>
class B
{
    // ...
};

J'ai donc deux classes, A et B, et une spécialisation de A pour le type int.
Maintenant, imaginons que je veux que B<int> fasse exactement la même chose que A<int> mais que ça ne soit valable que pour ce type-là sans avoir à recopier le corps de A<int> à la main dans B<int>.

En gros, en utilisant des typedefs, ça donnerait :
Code: [Select]
// C++03
typedef A<int> B<int>;

// C++11
using B<int> = A<int>;

Mais bon, aucune des deux écritures n'est valide. Donc mon problème reste complet. La seule méthode que je vois est complètement sale, mais je vous la présente quand, ne serait-ce que pour vous faire hurler :

Code: (body.h) [Select]
// ...
// Code contenu dans A<int> et B<int>

Code: (AB.h) [Select]
template<typename T>
class A
{
    // ...
};

template<>
class A<int>
{
    #include "body.h"
};

template<typename T>
class B
{
    // ...
};

template<>
class B<int>
{
    #include "body.h"
};

Ceci dit, j'ai une certaine éthique qui m'empêche de coder comme ça, d'autant plus que le code serait chargé deux fois tandis qu'il est le même dans les deux classes.
Bref, c'est simplement pour pouvoir faire des alias de spécialisations, mais j'ai bien l'impression qu'il est impossible de faire quelque chose comme ça malheureusement dans le langage ;)

Ceci dit, je ne pense pas toujours à tout, donc je vous laisse y réfléchir si vous avez une solution à proposer^^
Journalisée

Noxneo
Guest


Courriel
« Répondre #1 le: 28 Avril 2012 à 23:41 »

Dans ta solution crado, le code ne serait pas "chargé" 2 fois— les directives #include sont traitées par le préprocesseur, donc ça serait comme si t'avais fait un gros copier coller. L'exécutable produit ne serait pas plus crade qu'avec une autre méthode.

Cela dit, j'ai l'impression que tu es en train d'utiliser le mauvais outil pour ton problème (les template c'est utile, mais il faut s'en servir avec des grosses pinces).

Quel est le problème exact et concret que tu souhaites résoudre?
Journalisée
Morwenn
Sheikah
*
Offline Offline

Messages: 3 266


And so what?


WWW Courriel
« Répondre #2 le: 29 Avril 2012 à 12:23 »

Quand je dis "chargé deux fois", c'est à dire que ça va me compiler le code pour la classe A<int> et B<int> indépendamment alors que concrètement, ça pourrait indiquer au compilateur d'utiliser les deux spécialisations de classes de la même manière ;)

Après, j'étais juste en train de me repencher à titre expérimental (comme toujours quand j'ai des problèmes que je poste ici) sur une petite API de géométrie permettant en autres de manipuler des objets géométriques dans des espaces de dimension N. Ainsi, je me retrouve avec des classes template Point<N>, Line<N>, etc...
Et donc en fait, le seul paramètre template est un entier. De là, on pourrait se demander pourquoi utiliser des templates plutôt que d'utiliser un simple paramètre pour spécifier la dimension (ce qui était le cas au début). Alors, dans un premier, utiliser des templates permet de détecter les erreurs à la compilation (genre qu'il est impossible de faire une comparaison entre un Point<2> et un Point<3>), ce qui fait qu'on gagne des erreurs documentés, et énormément de vérifications en moins à l'exécution. J'ai retourné le choix de nombreuses fois dans ma tête, et ça m'a paru être le bon :P

BREF. Pour revenir à mon problème actuel, j'ai des spécialisations de pas mal d'objets pour les dimensions 2 et 3 (parce que je ne trouve pas toujours des algorithmes génériques pour tout gérer dans des espaces de dimension N) et il s'avère que certains objets sont les mêmes dans des espaces de certaines dimensions. Par exemple, une hypersphère dans un espace de dimension 2 est aussi un cercle, autre objet géométrique. Du coup, j'aurais voulu pouvoir faire un truc comme ça :
Code: [Select]
using Cercle<2> = Hypersphere<2>;

Après, ce n'est que de l'expérimental, et je ne ai pas fondamentalement besoin, mais techniquement, c'est bien de pouvoir réutiliser du code plutôt que de devoir le manipuler de manière identique à différents endroits.


EDIT: Niveau possibilités, y'a aussi moyen de faire
Code: [Select]
template<>
Cercle<2>: public Hypersphere<2>
{};

Mais bon, les classes ne pourront pas être utilisées comme équivalents stricts. Bref. J'irais probablement vers un truc de ce style. Dommage qu'il n'y ait pas de solution imbattable là-dessus^^"
« Dernière édition: 29 Avril 2012 à 19:28 par Morwenn » Journalisée

Noxneo
Guest


Courriel
« Répondre #3 le: 21 Mai 2012 à 08:46 »

J'avais oublié ce topic.

Oui, tu tombes dans l'un des gros problèmes conceptuels de la programmation objet. Comme tu es en train de le réaliser, il y'a plein de cas (dans le monde réel comme dans le monde abstrait) où l'on ne peut pas clairement définir des objets en tant qu'entités distinctes avec optionellement une relation d'héritage. [ 1] Ce que tu es en train de vivre n'est qu'une version plus complexe du problème cercle/ellipse [3].

La programmation objet est fantastique dans beaucoup d'applications (surtout le développement de jeu vidéo et d'interfaces utilisateurs), mais n'est pas une solution à tout comme pourrait le prétendre certains. C'est, entre autres, pour des raisons de ce genre que Torvalds code le noyau Linux seulement en C et ne veut pas transitioner au C++. [ 0]

Tu veux peut être regarder du côté du "component based design". En lien [2] un post qui recense pas mal de ressources, orientées dev de JV, mais au final c'est applicable ailleurs.

[ 0]: http://harmful.cat-v.org/software/c++/linus
[ 1]: http://okmij.org/ftp/Computation/Subtyping/
[ 2]: http://stackoverflow.com/questions/1901251/component-based-game-engine-design
[ 3]: http://en.wikipedia.org/wiki/Circle-ellipse_problem
Journalisée
Morwenn
Sheikah
*
Offline Offline

Messages: 3 266


And so what?


WWW Courriel
« Répondre #4 le: 21 Mai 2012 à 19:50 »

Bwahahah, je connaissais déjà ces messages de Linus. J'ai jamais vraiment prôné la non-évolution, mais il est très fort pour faire obstacle au changement de paradigme. Ça m'avait à la fois beaucoup fait rire et un peu pleurer je dois dire^^"

Pour le problème Cercle-Ellipse, je crois que ça résume bien le mur dans lequel je suis en train de rentrer en tentant de faire ce que je veux faire. Je n'en avais pas entendu parler jusque-là. Merci pour cette notion que j'ignorais complètement :P

Je vais jeter un coup d’œil au component based design du coup. Ça a l'air assez intéressant et je n'ai fait qu'en entendre parler jusque-là sans vraiment savoir à quoi ça correspondait. Merci dans tous les cas :)
Journalisée

Pages: [1] Imprimer 
Forums Zelda Solarus  |  Jeux amateurs  |  Programmation  |  Topic: [C++] Template typedef
Aller à:  

Propulsé par MySQL Propulsé par PHP Powered by SMF 2.0.15 | SMF © 2006, Simple Machines LLC XHTML 1.0 Transitionnel valide ! CSS valide !
Zelda Solarus 2009Skin par Eidarloy
Solarus-Games