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

récursion sur un membre template d'une class template

22 réponses
Avatar
AG
Bonjour,

Est-il seulement possible de faire ceci, et si oui comment (car ce code ne
compile pas)

Merci d'avance,

Alexandre.

#define N 20

template<class T> class A
{
public:
template<int D> void f(T *a);
};

template<class T> template<int D> void A<T>::f<D>(T *a)
{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
f<D-1>(a+10);
}

template<class T> template<> void A<T>::f<0>(T * a)
{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
}

int main()
{
A<int> monObjet;
int tab[N];
monObjet.f<1>(tab);
return 0;
}

10 réponses

1 2 3
Avatar
Jean-Marc Bourguet
"AG" writes:

Bonjour,

Est-il seulement possible de faire ceci, et si oui comment (car ce code
ne compile pas)


Non. Il y a une erreur (corrigee plus bas) et une chose impossible.

Merci d'avance,

Alexandre.

#define N 20

template<class T> class A
{
public:
template<int D> void f(T *a);
};

template<class T> template<int D> void A<T>::f<D>(T *a)
template<class T> template<int D> void A<T>::f(T* a)

{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
f<D-1>(a+10);
}

template<class T> template<> void A<T>::f<0>(T * a)
Impossible, il faut specialiser explicitement tous les templates englobant.

{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
}

int main()
{
A<int> monObjet;
int tab[N];
monObjet.f<1>(tab);
return 0;
}




--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Michael DOUBEZ
"AG" writes:

Bonjour,

Est-il seulement possible de faire ceci, et si oui comment (car ce code
ne compile pas)


Non. Il y a une erreur (corrigee plus bas) et une chose impossible.


#define N 20

template<class T> class A
{
public:
template<int D> void f(T *a);
};

template<class T> template<int D> void A<T>::f<D>(T *a)
template<class T> template<int D> void A<T>::f(T* a)

{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
f<D-1>(a+10);
}

template<class T> template<> void A<T>::f<0>(T * a)
Impossible, il faut specialiser explicitement tous les templates englobant.

{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
}

int main()
{
A<int> monObjet;
int tab[N];
monObjet.f<1>(tab);
return 0;
}



Il doit être possible de contourner ça en utilisant une structure helper:

template<class T>
template<int D> void A<T>::f(T* a)
{
A_f_helper<T,D,(D>0)>::f(a);
}

Avec
//j'utilise un predicat P pour l'arret - peut être l'utilisation d'un
unsigned peut être utilisé pour D
template<class T,int D, bool P>
struct A_f_helper;

template<class T,int D>
struct A_f_helper<T,D,true>
{
static void f(T* a)
{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
A_f_helper<T,D-1,((D-1)>0)>::f(a+10);
}
};

template<class T,int D>
struct A_f_helper<T,D,false>
{
static void f(T* a)
{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
}
};


Michael


Avatar
AG
Merci Michael, pour cette ouverture. Quid du code ci-dessous, qui compile,
si j'ai la possibilité de modifier les parametres templates de la class A ?

Alexandre.

#define N 20

template<class T,int D> class A
{
public:
void f(T *a);
};

template<class T, int D> void A<T,D>::f(T*a)
{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
A<T,D-1>::f(a+10);
};

template<class T> class A<T,0>
{
public:
void f(T*a)
{
int i;
for(i=0;i<9;i++)
a[i+1]+=a[i];
};
};

int main()
{
A<int,1> monObjet;
return 0;
}
Avatar
Jean-Marc Bourguet
"AG" writes:

Merci Michael, pour cette ouverture. Quid du code ci-dessous, qui compile,
si j'ai la possibilité de modifier les parametres templates de la class A ?


Ca marche aussi. Mais j'etais (et Michael aussi je suppose) parti sur
l'hypothese que ta classe A contenaient d'autres membres pour lesquels le
parametre D n'a pas de sens. Une autre approche est de faire de f une
fonction libre (et amie de A si necessaire).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
AG
Ca marche aussi. Mais j'etais (et Michael aussi je suppose) parti sur
l'hypothese que ta classe A contenaient d'autres membres pour lesquels le
parametre D n'a pas de sens.
ok.



Une autre approche est de faire de f une
fonction libre (et amie de A si necessaire).
ça m'intéresse. Une bonne simplification de ma class A est celle que j'ai

donnée :

template<class T> class A
{
public:
template<int D> void f(T * a);
};

et il me faut D-1 fonctions f() dans ma class A. Mon code C++ étant
réinterprété par un outil qui ne comprend que le mécanisme de récursivité
sur les fonctions templates, j'avais imaginé la solution initialement
proposée mais malheureusement impossible. La solution "fonction helper"
ainsi que celle que j'ai proposé en second lieu ne conviennent pas car elles
font usage de la récursivité sur les class (et pas les fonctions). Je vais
tenter la "fonction amie". Je posterais ma solution si je suis bloqué et que
j'ai besoin d'un coup de main.

Ou peut-on trouver une version à peu près à jour du dernier standard ? car
de temps en temps, c'est bien de savoir ce que l'on peut faire, et ce que
l'on ne peut pas faire.

Alexandre.

Avatar
Fabien LE LEZ
On Wed, 8 Aug 2007 14:19:23 +0200, "AG" :

Ou peut-on trouver une version à peu près à jour du dernier standard ?


http://groups.google.com/group/fr.comp.lang.c++/msg/48d73cd41e43cd7?hl=fr

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

On Wed, 8 Aug 2007 14:19:23 +0200, "AG" :

Ou peut-on trouver une version à peu près à jour du dernier standard ?


http://groups.google.com/group/fr.comp.lang.c++/msg/48d73cd41e43cd7?hl=fr
Merci Fabien. En fait, ces liens là je les avais. Par contre, je pensais

qu'il y avait surement un draft émis juste avant la version finale qui
serait peut être pas tout à fait à jour, mais suffisant pour l'utilisation
que j'en fait, et qui serait gratuit ? Je rêve ?

AG.

PS : j'ai commencé les GotW. Je ne connaissait pas, c'est intéressant.


Avatar
Fabien LE LEZ
On Wed, 8 Aug 2007 14:41:31 +0200, "AG" :

Par contre, je pensais
qu'il y avait surement un draft émis juste avant la version finale qui
serait peut être pas tout à fait à jour, mais suffisant pour l'utilisation
que j'en fait, et qui serait gratuit ? Je rêve ?


http://groups.google.com/group/fr.comp.lang.c++/msg/232d6ef8bc768474?hl=fr

PS : j'ai commencé les GotW. Je ne connaissait pas, c'est intéressant.


Yep, une fois que tu as compris tout ce que Sutter dit là-dedans, tu
commences à avoir un début de vision de ce qu'est le C++...

Avatar
Jean-Marc Bourguet
"AG" writes:

Ca marche aussi. Mais j'etais (et Michael aussi je suppose) parti sur
l'hypothese que ta classe A contenaient d'autres membres pour lesquels le
parametre D n'a pas de sens.
ok.



Une autre approche est de faire de f une
fonction libre (et amie de A si necessaire).
ça m'intéresse. Une bonne simplification de ma class A est celle que j'ai

donnée :

template<class T> class A
{
public:
template<int D> void f(T * a);
};


En quoi la classe est necessaire et

template<class T, int D> void f(T* a);

ne conviens pas? Est-ce que

template <class T> class A;
template <class T, int D> void f(T* a, A<T>& inst);
template <class T> class A
{
public:
friend template <int D> void f<T, D>(T* a, A<T>& inst);
};
ne conviendrait pas?

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Michael DOUBEZ
Une autre approche est de faire de f une
fonction libre (et amie de A si necessaire).
ça m'intéresse. Une bonne simplification de ma class A est celle que j'ai

donnée :

template<class T> class A
{
public:
template<int D> void f(T * a);
};

et il me faut D-1 fonctions f() dans ma class A. Mon code C++ étant
réinterprété par un outil qui ne comprend que le mécanisme de récursivité
sur les fonctions templates, j'avais imaginé la solution initialement
proposée mais malheureusement impossible. La solution "fonction helper"
ainsi que celle que j'ai proposé en second lieu ne conviennent pas car elles
font usage de la récursivité sur les class (et pas les fonctions). Je vais
tenter la "fonction amie". Je posterais ma solution si je suis bloqué et que
j'ai besoin d'un coup de main.


Si je résume, tu as besoin de D fonctions membres définies de façon
recursives mais avec une reccursivité sur les fonctions. Ce n'est pas
possible mais avec un D maximal une possibilité est d'utiliser l'heritage.

template<int D>
struct A_Discriminator{};

template<class T,int D>
struct A_Base: A_Base<T,D-1>
{
public:
void f(T * a,A_Discriminator<D>)
};

template<class T>
struct A_Base<T,0>
{
public:
void f(T * a,A_Discriminator<0>);
};

template<class T,int DMAX> class A: A_Base<T,DMAX>
{
template<int D> void f(T * a)
{
this->f(a,A_Discriminator<D>());
}
}


Si tu as basoin d'acceder à des membre de A, tu peux utiliser CRTP pour
y acceder.



Ou peut-on trouver une version à peu près à jour du dernier standard ? car
de temps en temps, c'est bien de savoir ce que l'on peut faire, et ce que
l'on ne peut pas faire.


Ton message réponse n'est pas apparu sur free pour une raison connue de
lui seul (idem pour certains messages dans des groupes modérés).

Michael


1 2 3