templates, spécialisations ...

Le
Ploc
Bonjour,

J'essaie de coder un tableau multi-dimmensionnel à base de templates.
C'est surtout pour la compréhension des mécanismes.
En cas réel, j'utiliserai probablement le boost::multi_array.

Au final, j'ai une classe myarray template qui fournit quelques services
de base et qui contient une classe template array_impl encapsulant le
tableau en lui même.

Maintenant, je veux faire un resize :
1/ si j'ai un type de array_impl<my_array<T> >, je veux redimmensionner
le tableau et chacun de ses éléments.
2/ Si j'ai un type différent (typiquement un double, int, string), je
ne veux redimmensionner que le tableau.

Pour l'instant, j'ai :

template <typename T>
class array_impl
{
public:
void resize(const vector<int> new_sizes); // resize recursif (point 1/)

};

template <>
class array_impl<double>
{
void resize(const vector<int> new_sizes); // resize uniquement ce
tableau (point 2/)

};


Ce qui ne me plait pas du tout :
- Le problème: il faut redéfinir le comportement 2/ pour chaque type
de base potentiellement utilisable par ce tableau.
- et surtout, il me semble que le comportement par défaut devrait être
le resize du point 2/.

Et la je bloque car je ne sais pas (ni même si c'est possible) exprimer
une classe template ou une spécialisation de la forme:
template <>
class array_impl< myarray<T> >
{
}

Peut-on faire quelque chose de ce style?


Merci,
P.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fabien LE LEZ
Le #17805921
On Mon, 10 Nov 2008 15:41:58 +0100, Ploc
template <typename T>
class array_impl
{
public:
void resize(const vector<int> new_sizes); // resize recursif (point 1/)



Ben non. Par défaut, resize() n'est pas récursif.
Ce n'est que dans le cas particulier où l'argument template est un
myarray<>, que resize() est récursif.

// Cas général (2/) :

template <class T> struct array_impl
{
void resize() { std::cout << "non récursifn"; }
};

// Cas particulier -- spécialisation (1/) :

template <class U> struct array_impl <myarray<U> >
{
void resize() { std::cout << "récursifn"; }
};
Ploc
Le #17806751
Fabien LE LEZ wrote:
On Mon, 10 Nov 2008 15:41:58 +0100, Ploc
template <typename T>
class array_impl
{
public:
void resize(const vector<int> new_sizes); // resize recursif (point 1/)



Ben non. Par défaut, resize() n'est pas récursif.
Ce n'est que dans le cas particulier où l'argument template est un
myarray<>, que resize() est récursif.

// Cas général (2/) :

template <class T> struct array_impl
{
void resize() { std::cout << "non récursifn"; }
};

// Cas particulier -- spécialisation (1/) :

template <class U> struct array_impl <myarray<U> >
{
void resize() { std::cout << "récursifn"; }
};




J'espérais bien qu'il existait une méthode pour ca.
Merci!

(Je regarderai le Stroustrup d'un peu plus près la prochaine fois...)
Fabien LE LEZ
Le #17864461
On Tue, 11 Nov 2008 10:22:19 +0100, Ploc
(Je regarderai le Stroustrup d'un peu plus près la prochaine fois...)



Sais pas si le Stroustrup t'aiderait beaucoup dans ce cas-là.

L'idée quand on a affaire aux templates, est de commencer par le cas
le plus général (type quelconque), et ensuite de se préoccuper des cas
particuliers (type = myarray<>).
Michael DOUBEZ
Le #17869811
Fabien LE LEZ a écrit :
On Mon, 10 Nov 2008 15:41:58 +0100, Ploc
template <typename T>
class array_impl
{
public:
void resize(const vector<int> new_sizes); // resize recursif (point 1/)



Ben non. Par défaut, resize() n'est pas récursif.
Ce n'est que dans le cas particulier où l'argument template est un
myarray<>, que resize() est récursif.

// Cas général (2/) :

template <class T> struct array_impl
{
void resize() { std::cout << "non récursifn"; }
};

// Cas particulier -- spécialisation (1/) :

template <class U> struct array_impl <myarray<U> >
{
void resize() { std::cout << "récursifn"; }
};




Je ne voit pas pourquoi il faudrait spécialiser toute la classe pour ne
spécialiser qu'une méthode. C'est un exemple typique de C++ moderne:

template<int val>
struct IntToType{enum {value=val};};

template <class T>
struct array_impl
{
public:
void resize(){return resize<apply_recursive_resize<T>::value> >());}

private:
void resize(IntToType<false>) { std::cout << "non récursifn"; }
void resize(IntToType<true>) { std::cout << "récursifn"; }
};


Concernant apply_recursive_resize, ça peut être un type trait ou un test
pout savoir si la type a la méthode T::resize().


--
Michael
Fabien LE LEZ
Le #17874551
On Mon, 17 Nov 2008 10:25:13 +0100, Michael DOUBEZ

Je ne voit pas pourquoi il faudrait spécialiser toute la classe pour ne
spécialiser qu'une méthode.



Quand la classe n'a qu'une fonction, c'est 'achement plus simple.
Ploc
Le #17876681
Fabien LE LEZ wrote:
On Tue, 11 Nov 2008 10:22:19 +0100, Ploc
(Je regarderai le Stroustrup d'un peu plus près la prochaine fois...)



Sais pas si le Stroustrup t'aiderait beaucoup dans ce cas-là.

L'idée quand on a affaire aux templates, est de commencer par le cas
le plus général (type quelconque), et ensuite de se préoccuper des cas
particuliers (type = myarray<>).




En pratique j'avais fait le cas inverse, car je ne connaissais pas la
syntaxe pour le bon ordre.
Et après, j'ai trouvé dans le Stroustrup. C'est de suite plus facile de
trouver quand on sait quoi...

Merci encore.
Michael DOUBEZ
Le #17879411
Fabien LE LEZ a écrit :
On Mon, 17 Nov 2008 10:25:13 +0100, Michael DOUBEZ

Je ne voit pas pourquoi il faudrait spécialiser toute la classe pour ne
spécialiser qu'une méthode.



Quand la classe n'a qu'une fonction, c'est 'achement plus simple.




Ok mais je doute que ce soit le cas de array_impl<> ou alors il n'a pas
de données membre non plus et c'est plus informatif de le renommer
void_impl<> :)

--
Michael
Publicité
Poster une réponse
Anonyme