OVH Cloud OVH Cloud

Template, argument par defaut et declaration en avant

35 réponses
Avatar
Marc Boyer
Bonjour,

bon, je reprends un (gros) code C++, alors je vais avoir je crois pas
mal de questions.

Pour le moment, j'ai un problème de template + argument template par defaut
+ declaration en avant.

Soit une classe avec un argument template par defaut, genre
template <class T,
template <class X> cont= std::list>
class Collection {
T t;
cont<int> c;
};

J'ai besoin dans une autre classe de faire une déclaration en avant,
mais comme je ne fixe pas dans ce cas de valeur au 2ème argument
template, il faut que je fasse une déclaration en avant complète:
template <class T,
template <class X> cont= std::list>
class Collection;

Et quand je définis la classe, il rale d'une redéclaration
des arguments par défaut...

J'ai pensé à un fichier du genre
CollectionFwd.h
dans la même veine que
iosfwd
mais est-ce que je sors pas le marteau pour écraser une mouche ?

Est-ce qu'il y a des pratiques "habituelles" ?

Vous faites comment vous ?

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...

10 réponses

1 2 3 4
Avatar
Marc Boyer
Jonathan Mcdougall wrote:
Soit une classe avec un argument template par defaut, genre
template <class T,
template <class X> cont= std::list>
class Collection {
T t;
cont<int> c;
};


Premièrement, ça ne devrait pas compiler puisque std::list prend (au moins)
deux paramètres.


Mon g++ 3.2.2 l'accepte sans broncher, même en
-ansi -Wall -pedantic

Les arguments par défaut de std::list n'entrent pas en
compte ici. Il n'existe pas de moyen standard d'accomplir ceci, puisque les
implémentations sont libres d'ajouter un nombre quelconque paramètress'ils
ont des valeurs par défaut. Comme tu dois les spécifier, une implémentation
utilisant 3 paramètres casserait ton code. En passant, c'est un defect dans
le standard.


Ce que j'aime bien en C++, c'est qu'on arrive vite à mettre le
doigt sans le savoir sur des pb dans la norme.

Deuxièmement, il te manque un 'class' devant 'cont' :


Sorry, pb de copier/coller.

Tu vois que côté portabilité, ça laisse à désirer.


Je prends note.
Ceci dit, le code est actuellement plein de
_gnu_cxx
donc la portabilité est pas la priorité du moment. Sans
compter que ça utilise un bilbilothèque (nana) qui dit
explicitement avoir besoin de extensions GNU pour compiler,
donc, tant que ça accepte de compiler avec g++, je suis
content.

Tu n'as qu'un choix : omettre le paramètre par défaut dans la définition du
template. À partir de là, tu peux simplement copier la déclaration du
template là où tu en as besoin (possiblement dans le même fichier que
l'implémentation) ou simplement l'inclure par un header.

// mon_fwd.h
template <class T, template<class, class> class C = std::list>
class Collection;


Je me suis rabattu sur ça en effet.

Merci,
Marc
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...


Avatar
Marc Boyer
Jean-Marc Bourguet wrote:
Marc Boyer writes:

Jean-Marc Bourguet wrote:
Marc Boyer writes:
Donc, CollectionFwd.h ?


Oui. Protege contre la double inclusion, fournissant les arguments
par defaut et inclus dans le fichier avec la definition de la classe
template.


Vivement une gestion des modules en C++.


Tu as une proposition?


Non... J'ai des problèmes avec la solution actuelle, mais
pas de proposition.

C'est un des points ou j'ai chercher a
articuler mes desideratas mais je n'arrive pas a quelque chose qui
vaille la peine d'etre discutte.


Si tu veux lancer une discussion ici, je lirais avec plaisir.

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...




Avatar
Jean-Marc Bourguet
Gabriel Dos Reis writes:

Jean-Marc Bourguet writes:

| Marc Boyer writes:
|
| > Jean-Marc Bourguet wrote:
| > > Marc Boyer writes:
| > >> Donc, CollectionFwd.h ?
| > >
| > > Oui. Protege contre la double inclusion, fournissant les arguments
| > > par defaut et inclus dans le fichier avec la definition de la classe
| > > template.
| >
| > Vivement une gestion des modules en C++.
|
| Tu as une proposition? C'est un des points ou j'ai chercher a
| articuler mes desideratas mais je n'arrive pas a quelque chose qui
| vaille la peine d'etre discutte.

C'est loin d'être évident, surtout si on veut une compatibilité avec
l'existant.


C'etait bien ma conclusion. Mais un esprit neuf pouvait avoir l'idee
lumineuse que je n'ai pas eue a cause de mes prejuges.

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
Marc Boyer
Gabriel Dos Reis wrote:
Marc Boyer writes:
| Soit une classe avec un argument template par defaut, genre
| template <class T,
| template <class X> cont= std::list>

Ça ne marchera pas -- excepté si tu comptes sur le gros bug de GCC.
std::list prend deux arguments templates.


GCC est en effet mon compilateur, et avant que de venir demander
des conseils ici, je me repose sur son expertise à lui (qui est
bien au delà de la mienne).

Oui. Les arguments par défaut des templates marche à peu près comme
les arguments par défaut des fonctions -- cela définit une valeur.

|
| J'ai pensé à un fichier du genre
| CollectionFwd.h
| dans la même veine que
| iosfwd
| mais est-ce que je sors pas le marteau pour écraser une mouche ?


Bah pourquoi pas simplement

template<class T, template<class, class> class cont = std::list>
struct Collection;

// ...

template<class T, template<class, class> class cont>
struct Collection {
// ...
};


Pour un problème de maintenance: il y a plusieurs fichiers
qui ont besoin de cette déclaration en avant, et si un jour je
réalise que std::deque est une meilleure solution par
defaut, il vaudrait mieux que je n'ai qu'un seul fichier
à modifier.

Les paramètres templates de template, c'est un rigide, pourquoi pas
simplement une paramètre type ?


Heuh, je veux bien essayer si tu m'explique à quoi tu penses.

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...

Avatar
Jonathan Mcdougall
| deux paramètres. Les arguments par défaut de std::list n'entrent pas en
| compte ici. Il n'existe pas de moyen standard d'accomplir ceci, puisque
les

| implémentations sont libres d'ajouter un nombre quelconque
paramètress'ils

| ont des valeurs par défaut.

Ce n'est pas permis.


Et tu as bien raison, quoique si une issue a été proposée, c'est bien que je
ne suis pas le seul à l'avoir pensé. Il me semble bien avoir lu quelque
chose en ce sens à quelque part, mais je ne me souviens plus.

http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-closed.html#94


Désolé.


Jonathan

Avatar
Gabriel Dos Reis
"Jonathan Mcdougall" writes:

| > | deux paramètres. Les arguments par défaut de std::list n'entrent pas en
| > | compte ici. Il n'existe pas de moyen standard d'accomplir ceci, puisque
| les
| > | implémentations sont libres d'ajouter un nombre quelconque
| paramètress'ils
| > | ont des valeurs par défaut.
| >
| > Ce n'est pas permis.
|
| Et tu as bien raison, quoique si une issue a été proposée, c'est bien que je
| ne suis pas le seul à l'avoir pensé.

Je ne dis pas que tu es le seul à faire ce raisonnement. Je dis
simplement que ce raisonnement ne correspond pas à ce que le comité a
voulu et décidé.

| Il me semble bien avoir lu quelque
| chose en ce sens à quelque part, mais je ne me souviens plus.

Effectivement, il y a beaucoup de gens qui racontent beaucoup
d'histoires pour faire peur :-)

-- Gaby
Avatar
Gabriel Dos Reis
Marc Boyer writes:

| Jonathan Mcdougall wrote:
| >> Soit une classe avec un argument template par defaut, genre
| >> template <class T,
| >> template <class X> cont= std::list>
| >> class Collection {
| >> T t;
| >> cont<int> c;
| >> };
| >
| > Premièrement, ça ne devrait pas compiler puisque std::list prend (au moins)
| > deux paramètres.
|
| Mon g++ 3.2.2 l'accepte sans broncher, même en
| -ansi -Wall -pedantic

Oui, mais c'est un bug connu de GCC.

-- Gaby
Avatar
Gabriel Dos Reis
Marc Boyer writes:

[...]

| defaut, il vaudrait mieux que je n'ai qu'un seul fichier
| à modifier.

C'est sûr.

| > Les paramètres templates de template, c'est un rigide, pourquoi pas
| > simplement une paramètre type ?
|
| Heuh, je veux bien essayer si tu m'explique à quoi tu penses.


Au lieu d'avoir

template<class T, template<class, class T> class cont>
struct Collection {
};

Pourquoi pas

template<class T, class cont = std::list<T> >
struct Collection {
// ...
};

?

-- Gaby
Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

| Gabriel Dos Reis writes:
|
| > Jean-Marc Bourguet writes:
| >
| > | Marc Boyer writes:
| > |
| > | > Jean-Marc Bourguet wrote:
| > | > > Marc Boyer writes:
| > | > >> Donc, CollectionFwd.h ?
| > | > >
| > | > > Oui. Protege contre la double inclusion, fournissant les arguments
| > | > > par defaut et inclus dans le fichier avec la definition de la classe
| > | > > template.
| > | >
| > | > Vivement une gestion des modules en C++.
| > |
| > | Tu as une proposition? C'est un des points ou j'ai chercher a
| > | articuler mes desideratas mais je n'arrive pas a quelque chose qui
| > | vaille la peine d'etre discutte.
| >
| > C'est loin d'être évident, surtout si on veut une compatibilité avec
| > l'existant.
|
| C'etait bien ma conclusion. Mais un esprit neuf pouvait avoir l'idee
| lumineuse que je n'ai pas eue a cause de mes prejuges.

tu es trop modeste :-)

En ce moment, on réfléchit sur un système de module pour
« The Pivot (IPR/XPR) »

http://www-unix.mcs.anl.gov/workshops/DSLOpt/Talks/DosReis.pdf

et même là, le moins qu'on puisse dire, c'est qu'on fait, pour le
moment, des hypothèses sur les « programmes raisonnablement bien écrits
» :-)

-- Gaby
Avatar
Marc Boyer
Gabriel Dos Reis wrote:
Au lieu d'avoir

template<class T, template<class, class T> class cont>
struct Collection {
};

Pourquoi pas

template<class T, class cont = std::list<T> >
struct Collection {
// ...
};

?


Disons que l'exemple réel est bien plus enchevétré, et serait du
genre (et c'est encore une version simplifiée)

template< class Model,
class ArcList =
std::list< ArcModel< Model::Arc, Model::Action > >,
class NodeList =
std::list< NodeModel< Model::Node, Model::Action > > >
class StateSpace;

avec surement un ou deux typename à ajouter j'imagine pour dire que
Model::Node et Model::Action sont des noms de classe.

Alors, en première approche, j'avais découplé les deuxièmes et troisièmes
arguments templates du premier dans la déclaration pour ne
refaire le lien que dans la classe après une série de typedef...

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...

1 2 3 4