Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

membres statiques et spécialisations partielles de classes

13 réponses
Avatar
AG
Bonjour,

voici mon bout de code (toujours le même en amélioré). Ma question est la
suivante :

combien de tableau tab ai-je ? Moi j'en veux que deux. Un pour myA1 et un
pour myA2. Le fait que je sois obligé de spécialiser l'instanciation du
tableau statique tab me fait penser que j'aurais 12 tableau en tout. Est-ce
bien ça ?

D'avance merci.

Alexandre.


#define D 5

const int L=10;

template <class T,bool S,int N=0> class A
{
static T tab[D*L];
A<T,S,N+1> next;
public:
void f(void)
{
for(int i=0;i<L;i++) tab[N*L+i+1]+=tab[N*L+i];
next.f();
};
};

template<class T,bool S> class A<T,S,D>
{
static T tab[D*L];
public:
void f(void)
{
for(int i=0;i<S;i++) tab[D*L+i+1]+=tab[D*L+i];
};
};


template<class T, bool S,int N>
T A<T,S,N>::tab[D*L]={0};

template<class T, bool S>
T A<T,S,D>::tab[D*L]={0};

int main(void)
{
A<int,true> myA1;
A<int,false> myA2
myA1.f();
myA2.f();
}

10 réponses

1 2
Avatar
Fabien LE LEZ
On Fri, 10 Aug 2007 11:48:32 +0200, "AG" :

me fait penser que j'aurais 12 tableau en tout. Est-ce
bien ça ?


Tu as effectivement 12 classes différentes :

A<int,true,0>
A<int,true,1>
A<int,true,2>
A<int,true,3>
A<int,true,4>
A<int,true,5>
et la même chose avec false

Donc, tu as 12 fonctions f() différentes, et 12 variables tab
différentes.


Moi j'en veux que deux. Un pour myA1 et un
pour myA2.



Dans ce cas, il ne faut pas mettre tab comme membre de A, mais comme
membre d'une classe B :

template <class T, bool S> class B
{
static T tab[D*L];
friend class A;
};

template <class T,bool S,int N=0> class A
{
A<T,S,N+1> next;
public:
void f()
{
for(int i=0;i<L;i++) B<T,S>::tab[N*L+i+1] += B<T,S>::tab[N*L+i];


PS : je suppose qu'il est inutile de s'appesantir sur le #define et le
paramètre "void" de f(), car tu n'as pas vraiment le choix à cause de
ton outil particulier ?

Avatar
Fabien LE LEZ

Dans ce cas, il ne faut pas mettre tab comme membre de A, mais comme
membre d'une classe B :


En fait, non. Si ton code client n'utilise pas le troisième paramètre
template de A, il ne faut pas qu'il soit public. Il faudrait donc
écrire :


template <class T, bool S>
class ClassePublique
{
public:
void f() { ClassePrivee<T,S,0>::f(); }

private:
template <class T, bool S, int N> struct ClassePrivee
{
static T tab[D*L];
ClassePrivee<T,S,N+1> next;
void f();
};
};

Avatar
AG
Tu as effectivement 12 classes différentes :
Ok, plus j'y repensais plus c'etait logique.


Dans ce cas, il ne faut pas mettre tab comme membre de A, mais comme
membre d'une classe B :
ok




PS : je suppose qu'il est inutile de s'appesantir sur le #define et le
paramètre "void" de f(), car tu n'as pas vraiment le choix à cause de
ton outil particulier ?
En fait, le parseur de mon outils reprends un parseur C++ quelconque, donc

tout ce qui est conforme C++ est normalement valide, sur la syntaxe. C'est
plus les constructions bizarres, les références, etc.. qui ne sont pas
acceptées. (je sais, c'est pas clair, mais même pour moi la frontière est
plutôt vague). le "void" de f n'est pas indispensable, il ne faut pas le
mettre ? je suis toujours avide de commentaires sur le style du code, je
début en C++.

AG.

Avatar
Fabien LE LEZ
On Fri, 10 Aug 2007 12:10:31 +0200, "AG" :

le "void" de f n'est pas indispensable, il ne faut pas le
mettre ?


Le paramètre "void" est un truc typique du C. Et encore, d'une très
vieille version du C.
En C moderne et en C++, il vaut mieux ne pas le mettre effectivement.
Bien sûr, le type de retour est indispensable (contrairement au même
vieux C, d'ailleurs) :

void f();

Avatar
AG
template <class T, bool S>
class ClassePublique
{
public:
void f() { ClassePrivee<T,S,0>::f(); }

private:

template <class T, bool S, int N> struct ClassePrivee
{
static T tab[D*L];
ClassePrivee<T,S,N+1> next;
void f();
};
};


C'est ce que je pensais faire au début, mais ta solution de classe amie est
plus appropriée à mon avis.
Dans ton exemple ci-dessus, tu as remis tab dans la class ClassPrivee, ce
qui me refait 12 tableau au lieu d'un par class ClassPublique.

Mais si tu le met en membre privé de la class ClassPublique, en dehors de la
class ClassPrivee, je vais avoir des problèmes d'accès à tab dans la
fonction f() non ? L'instance ClassPrivee<T,S,0> aura acces à tab, mais les
instances suivantes ClassPrivee<T,S,1>, ClassPrivee<T,S,2>, etc... n'y
auront plus accès ?

AG.

Avatar
Fabien LE LEZ
On Fri, 10 Aug 2007 13:37:30 +0200, "AG" :

Dans ton exemple ci-dessus, tu as remis tab dans la class ClassPrivee, ce
qui me refait 12 tableau au lieu d'un par class ClassPublique.


Oups, oui, c'est une erreur de ma part.

Au finale, tu as trois classes :

- une unique classe publique, ayant deux paramètres template, car le
code utilisateur ne doit pas avoir accès au troisième paramètre
template ;
- une classe ayant deux paramètres template, contenant tab ;
- une classe ayant trois paramètres template, contenant
l'implémentation de f().

Les deux premières peuvent être confondues (i.e. une seule classe), ou
pas.
Les deux dernières devraient être membres privés de la première, ou
plus généralement inaccessibles au code client.

Avatar
AG
J'en suis là. Mais ça bloque, parce que dans A<T,S,N>::f(), tab undeclared,
first use in this function. Je suis un peu bloqué,

#define D 5

const int L;

template<class T, bool S, int N=0> class A
{
public:

A<T,S,N+1> next;
void f();
};

template<class T,bool S, int N=0> class B
{
T tab[D*L+1];
A<T,S,N> a;
public:
friend void A<T,S,N>::f();

void f() {a.f();};
};



template <class T,bool S,int N>
void A<T,S,N>::f()
{
for(int i=0;i<L;i++) tab[N*L+i+1]+=tab[N*L+i];
next.f();
}

template<class T,bool S> class A<T,S,D>
{
public:
void f()
{
for(int i=0;i<S;i++) tab[D*L+i+1]+=tab[D*L+i];
};
};


int main()
{
A<int,true> myA1;
A<int,false> myA2;
myA1.f();
myA2.f();
}
Avatar
AG
#define D 5

const int L;

template<class T, bool S, int N=0> class A
{
public:

A<T,S,N+1> next;
void f();
};

template<class T,bool S, int N=0> class B
{
static T tab[D*L+1];

A<T,S,N> a;
public:
friend void A<T,S,N>::f();

void f() {a.f();};
};



template <class T,bool S,int N>
void A<T,S,N>::f()
{
for(int i=0;i<L;i++) B<T,S,N>::tab[N*L+i+1]+=B<T,S,N>::tab[N*L+i];
next.f();
}

template<class T,bool S> class A<T,S,D>
{
public:
void f()
{
for(int i=0;i<S;i++) B<T,S,D>::tab[D*L+i+1]+=B<T,S,D>::tab[D*L+i];
};
};

template<class T, bool S, int N> B<T,S,N>::tab[D*L+1]={0};


int main()
{
A<int,true> myA1;
A<int,false> myA2;
myA1.f();
myA2.f();
}


roulez jeunesse !

AG.

Avatar
Fabien LE LEZ
On Fri, 10 Aug 2007 16:32:18 +0200, "AG" :

template<class T,bool S, int N=0> class B
{
static T tab[D*L+1];



Mais tu te retrouves toujours avec 12 tableaux, non ?

En fait, tu as deux classes avec un "int N=0>" alors qu'il n'en
faudrait qu'une.


Avatar
AG
"Fabien LE LEZ" a écrit dans le message de news:

On Fri, 10 Aug 2007 16:32:18 +0200, "AG" :

template<class T,bool S, int N=0> class B
{
static T tab[D*L+1];



Mais tu te retrouves toujours avec 12 tableaux, non ?
non car la récursion est fait dans la class A, pas dans la class B.



En fait, tu as deux classes avec un "int N=0>" alors qu'il n'en
faudrait qu'une.
j'en ai deux dans le sens ou pour l'une S vaut true, et pour l'autre, S vaut

false. Mais ça c'était voulu.



1 2