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

parametre template

8 réponses
Avatar
AG
Bonjour,

j'ai un parametre template comme ça :


template<class T, template<typename> class ACS> class A
{
private:
ACS<T> foo;
};

template<class T> class ACS
{
public:
ACS(){};
T operator()(vector<T> & in);
};

et lors de l'instanciation de mon objet, je le fait comme ça :

A<maClassA,ACS> a;

Si je code ce petit exemple, ça marche, mais dans mon code en grandeur
nature, ça ne fonctionne pas. Je pense que c'est parce que
j'utilise ACS<maClassA> à certains endroits, et ACS<maClassB> à
d'autres endroits.

Je suspecte donc le fait que le compilo n'arrive pas à choisir (ou
choisi mal) le parametre template de l'ACS. et quand il arrive dans
l'objet foo, et qu'il fait le check des types, il voit qu'il a choisi
le ACS<maClassB> au lieu de ACS<maClassA> (le compilo me dit
clairement que les types ne corresondent pas dans la fonction/objet
foo()).

Je pensais pouvoir résoudre le problème en instanciant :

A<maClassA,ACS<maClassA> > a;

mais le compilo ne veut rien savoir, il n'accepte pas.

Comment dois-je faire ?

AG.

8 réponses

Avatar
AG
Visiblement, mon code est bon, le problème n'est pas là.

si je fais :

class A
{
public:
typedef int TA;
}

lequel des deux types dois-je utiliser :

TA ou A::TA ?

Est-ce que TA tout seul peut marcher ?

AG.
Avatar
Michael DOUBEZ
Bonjour,

j'ai un parametre template comme ça :


template<class T, template<typename> class ACS> class A
{
private:
ACS<T> foo;
};

template<class T> class ACS
{
public:
ACS(){};
T operator()(vector<T> & in);
};



Evites les conflits de nom: ACS est utilisés en tant que nom de
parametre de template et puis en tant que parametre propre.

Tu peux utiliser par exemple:

template<class T, template<typename> class ACSTemplate> class A
{
private:
ACSTemplate<T> foo;
};

Mais le mieux est de mettre un nom qui represente le concept que tu veux
représenter.


et lors de l'instanciation de mon objet, je le fait comme ça :

A<maClassA,ACS> a;


Tu peux rendre ACS optionnel par:
template<class T, template<typename> class ACSTemplate¬S> class A ...


Si je code ce petit exemple, ça marche, mais dans mon code en grandeur
nature, ça ne fonctionne pas. Je pense que c'est parce que
j'utilise ACS<maClassA> à certains endroits, et ACS<maClassB> à d'autres
endroits.

Je suspecte donc le fait que le compilo n'arrive pas à choisir (ou
choisi mal) le parametre template de l'ACS. et quand il arrive dans
l'objet foo, et qu'il fait le check des types, il voit qu'il a choisi le
ACS<maClassB> au lieu de ACS<maClassA> (le compilo me dit clairement que
les types ne corresondent pas dans la fonction/objet foo()).


Dans le combat humain contre compilateur, le compilateur part gagnant
sur l'application du standard.
Est ce que tu passe bien un vecteur de maClassA à ACS<maClassA>::foo()
et prends un maClassA en retour ?


Je pensais pouvoir résoudre le problème en instanciant :

A<maClassA,ACS<maClassA> > a;


Ton deuxieme parametre doit être un template.


mais le compilo ne veut rien savoir, il n'accepte pas.


C'est son job, en c++ en tout cas :)

Michel

Avatar
Sylvain
AG wrote on 19/07/2007 12:00:

class A {
public:
typedef int TA;
};

lequel des deux types dois-je utiliser :
TA ou A::TA ?


cela dépends du contexte.
dans le contexte de A (donc avec un A:: implicite) TA suffit, à
l'extérieur (donc dans ::), A::TA est requis; par exemple:

class A {
public:
typedef int TA;
TA foo() { return 0; }
};

ou

class A {
public:
typedef int TA;
TA foo();
};

A::TA A::foo() { return 0; }

dans les 2 cas, une lvalue externe s'écrit A::TA
(ie A::TA ta = A().foo();)

Sylvain.

Avatar
Michael DOUBEZ
Visiblement, mon code est bon, le problème n'est pas là.

si je fais :

class A
{
public:
typedef int TA;
}

lequel des deux types dois-je utiliser :

TA ou A::TA ?

Est-ce que TA tout seul peut marcher ?


Si tu est dans le scope de A (dans une fonction membre), tu peux
utiliser TA sinon, tu ne peux utiliser que A::TA.
ADL ne fonctionne que sur les noms de fonction.


Voilà un liens interressant que je viens de voir dans comp.lang.c++:
http://www-h.eng.cam.ac.uk/help/tpl/languages/C++/lookup.html

Michael

Avatar
AG
Evites les conflits de nom: ACS est utilisés en tant que nom de
parametre de template et puis en tant que parametre propre.
ok, je comprends.



Mais le mieux est de mettre un nom qui represente le concept que tu
veux représenter.
yep.



Tu peux rendre ACS optionnel par:
template<class T, template<typename> class ACSTemplate¬S> class A
...
c'est ce que j'ai fini par comprendre en googlant sur template

template.
J'ai aussi lu que ça ne faisait pas parti de la norme. Quel est le
statut officiel maintenant.

Dans le combat humain contre compilateur, le compilateur part
gagnant sur l'application du standard.
Est ce que tu passe bien un vecteur de maClassA à
ACS<maClassA>::foo() et prends un maClassA en retour ?
Je crois bien que ne suis qu'un humain. le problème était bien là. Le

compilo me disait un truc du genre :

cannot convert T [2] into vector<Ty> &
with
T = maClassA;
Ty = maClassB;

j'ai focalisé sur le fait que T et Ty était différent et ne devaient
pas l'être alors que le problème venait de la convertion vector <->
[].

Merci pour cette lumière bienvenue.

AG.

Avatar
Michael DOUBEZ
Visiblement, mon code est bon, le problème n'est pas là.

si je fais :

class A
{
public:
typedef int TA;
}

lequel des deux types dois-je utiliser :

TA ou A::TA ?

Est-ce que TA tout seul peut marcher ?


Si tu est dans le scope de A (dans une fonction membre), tu peux
utiliser TA sinon, tu ne peux utiliser que A::TA.
ADL ne fonctionne que sur les noms de fonction.


ADL n'a rien a voir la dedans, je pensais au namespace.

Michael


Avatar
Michael DOUBEZ
Tu peux rendre ACS optionnel par:
template<class T, template<typename> class ACSTemplate¬S> class A ...
c'est ce que j'ai fini par comprendre en googlant sur template template.

J'ai aussi lu que ça ne faisait pas parti de la norme. Quel est le
statut officiel maintenant.


Tu dois parler des 'concept' pour la prochaine norme. Ils formalisent au
niveau du compilateur les concepts pre-existant et permettent (pour ce
que j'en comprends) de faire de la metaprogrammation à la boost mais
plus evolué, avec un check des concepts et je l'espère des messages de
debug plus clair.
Je ne connais pas bien la chose mais j'ai l'impression qu'il sera de
plus en plus difficile de savoir ce qui est compilé à moins de connaitre
dans les grandes largeurs les méthodes d'overloading du c++.

Tu peux aller voir le tuto à:
http://www.generic-programming.org/languages/conceptcpp/

Mais, ce dont je parlais est de nommer ton parametre de façon
significative comme InputIterator, Predicate, Allocator ... dans la STL.

Michael


Avatar
Michael DOUBEZ
C'est pas ma journée (Voir pas mon mois).
Je repondais à:

Mais le mieux est de mettre un nom qui represente le concept que tu
veux représenter.


yep.


Tu peux rendre ACS optionnel par:
template<class T, template<typename> class ACSTemplate¬S> class A ...
c'est ce que j'ai fini par comprendre en googlant sur template template.

J'ai aussi lu que ça ne faisait pas parti de la norme. Quel est le
statut officiel maintenant.


Tu dois parler des 'concept' pour la prochaine norme. Ils formalisent au
niveau du compilateur les concepts pre-existant et permettent (pour ce
que j'en comprends) de faire de la metaprogrammation à la boost mais
plus evolué, avec un check des concepts et je l'espère des messages de
debug plus clair.
Je ne connais pas bien la chose mais j'ai l'impression qu'il sera de
plus en plus difficile de savoir ce qui est compilé à moins de connaitre
dans les grandes largeurs les méthodes d'overloading du c++.

Tu peux aller voir le tuto à:
http://www.generic-programming.org/languages/conceptcpp/

Mais, ce dont je parlais est de nommer ton parametre de façon
significative comme InputIterator, Predicate, Allocator ... dans la STL.



Pour ce qui est de template<class T, template<typename> class
ACSTemplate¬S> A...
C'est dans la norme paragraphe 14.1.

Michael