membres statiques et spécialisations partielles de classes
13 réponses
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();
}
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 ?
On Fri, 10 Aug 2007 11:48:32 +0200, "AG" <ag@tb.fr>:
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 ?
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 ?
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 :
private: template <class T, bool S, int N> struct ClassePrivee { static T tab[D*L]; ClassePrivee<T,S,N+1> next; void f(); }; };
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.
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++.
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.
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();
On Fri, 10 Aug 2007 12:10:31 +0200, "AG" <ag@tb.fr>:
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) :
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) :
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 ?
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 ?
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.
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.
On Fri, 10 Aug 2007 13:37:30 +0200, "AG" <ag@tb.fr>:
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.
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.
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();
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.
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.
"Fabien LE LEZ" <gramster@gramster.com> a écrit dans le message de news:
llepb39b311srp75cu1kbheculu2ajfmdq@4ax.com...
On Fri, 10 Aug 2007 16:32:18 +0200, "AG" <ag@tb.fr>:
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
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