OVH Cloud OVH Cloud

template typedef

3 réponses
Avatar
meow
Bonjour tout le monde,

Il me souvient qu'ici meme on m'avait enjoint =E0 diff=E9rencier les
types d'objets diff=E9rents, meme lorsque leur impl=E9mentation devait
etre la meme. Par exemple :
On devrait diff=E9rencier un *TriangularGrid* d'un *TriangularBezierNet*
d'un *TriangularBezierPatch* juste parce que ce ne sont pas les memes
objets, et meme si, en d=E9finitive, on les impl=E9mente de la meme
fa=E7on... En l'occurrence, j'ai un
template<class T> class TriangularGrid {
private :
int d; // degree
std::vector<T> grid; // stores the grid nodes
int map(int i,int j, int k) const throw (BezierErr) { // computes
index of node (i,j,k) in the grid vector
return ((d-i)*(d+1-i)/2 + k);
};

public :
//! trivial constructor
TriangularGrid(int d=3D0):d(d){ };
//! copy constructor
TriangularGrid(TriangularGrid const &gr){
d =3D gr.d;
grid=3Dgr.grid;
};
//! destructor
virtual ~TriangularGrid(){};

//! insert from vector
void load(TriangularGrid const &std::vector<T> vect){
if (vect.size()<d) throw (DegreeErr("Not enough values in this
vector"));
grid=3Dvect;
d=3D((int) (sqrt(1+8*vect.size()))) -1;
};
//! returns the degree of the grid
int degree() const {return d;}
//! returns a const ref to the node, for reading or call via const
functions
T const&
get(int i,int j,int k) const {
return grid[map(i,j,k)];}
//! returns a ref to the node, for modification
T&
get(int i,int j,int k){
return grid[map(i,j,k)];}
//! sets a node to a value
void set(int i,int j,int k, T const &p){grid[map(i,j,k)]=3Dp;};
};

et comme je suis flemmard et inquiet de toute redondance de code
j'aimerai ecrire un truc du genre :
template<class T> typedef TriangularGrid<T> TriangularBezierNet<T>
qui bien entendu ne fonctionne pas...

Mais peut etre finalement devrais-je plutot consid=E9rer la solution
consistant =E0 faire une super classe de mon TriangularGrid et =E0 la
d=E9river en BezierNet et BezierPatch... ?

3 réponses

Avatar
Loïc Joly
j'aimerai ecrire un truc du genre :
template<class T> typedef TriangularGrid<T> TriangularBezierNet<T>
qui bien entendu ne fonctionne pas...


Hélàs, les template typedefs n'existent pas. Et quand on regarde un peu
les détails, il n'y a pas 2 personnes pour être d'accord sur ce à quoi
ça devrait ressembler...

Peut-être un : typedef TriangularGrid<double> TriangularBezierNet

Est-il un pis-aller convenable.

--
Loïc

Avatar
kanze
Loïc Joly wrote:
j'aimerai ecrire un truc du genre :
template<class T> typedef TriangularGrid<T> TriangularBezierNet<T>
qui bien entendu ne fonctionne pas...


Hélàs, les template typedefs n'existent pas. Et quand on
regarde un peu les détails, il n'y a pas 2 personnes pour être
d'accord sur ce à quoi ça devrait ressembler...


Je ne suis pas sûr non plus qu'un typedef ferait réelement son
affaire. Si j'ai bien compris, ce qu'il veut, ce sont des types
distincts, pour ne pas pouvoir affecter un TriangularBezierNet à
un TriangularGrid, par exemple, ou que le surcharge de fonction
se résoud à une fonction différente selon le type. Ce que le
typedef ne fait pas -- malgré son nom, un typedef ne définit pas
un nouveau type ; il en crée un alias du nom seulement.

Pour en créer un nouveau type, la seule solution reste définir
une nouvelle classe. Si toutes ces classes aient exactement la
même implémentation, ou pour la partie de l'implémentation qui
est commune, il peut se servir soit de l'aggrégation, soit de
l'héritage privé, soit, s'il a des cas où il y a aussi des
fonctions qui peuvent traiter n'importe lequel des types
indifféremment, de l'héritage public. Reste que dans tous les
cas, il y a pas mal de boilerplate -- au dela d'un certain
point, l'utilisation des macros pour le générer se justifie.

Il y a une autre possibilité que je n'ai jamais expérimentée (et
donc je ne peux pas dire si elle fonctionne bien ou non) :
définir un enum avec les types, et l'utiliser comme paramètre du
template, c-à-d :

enum TriangularType
{
Grid,
BezierNet,
BezierPatch
} ;

template< typename T, TriangularType Type >
class Triangular
{
// ...
} ;

De la même manière, il pourrait définir des classes vides pour
chaque type réel, qu'il utiliser comme paramètre de template (un
peu comme un traits vide).

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
meow
wow... Encore plein de choses sympathiques à étudier.
Merci bien.