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
Jean-Marc Bourguet
Marc Boyer writes:

Vous faites comment vous ?


Il n'y a guere le choix: on ne peut donner les arguments par defaut
qu'une fois.

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
Jean-Marc Bourguet wrote:
Marc Boyer writes:

Vous faites comment vous ?


Il n'y a guere le choix: on ne peut donner les arguments par defaut
qu'une fois.


Donc, CollectionFwd.h ?

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
Marc Boyer writes:

Jean-Marc Bourguet wrote:
Marc Boyer writes:

Vous faites comment vous ?


Il n'y a guere le choix: on ne peut donner les arguments par defaut
qu'une fois.


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.

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
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++.

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
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. 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.

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

template <class T, template<class, class> class cont = std::list>
class Collection
{
T t;
cont<int, std::allocator<int> > c;
};

Normalement, ceci devrait compiler, mais ce n'est pas portable puisque
j'assume que std::list prend deux paramètres. Je répète que les arguments
par défaut ne s'appliquent pas et qu'il faut spécifier manuellement
std::allocator. Tu vois que côté portabilité, ça laisse à désirer.

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;


Ceci devrait être

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

Mais les mêmes remarques s'appliquent. Note filalement que j'ai omis les
noms dans le template de 'cont' : ils sont inutiles ou mêlant au mieux.

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


Oui, au même titre que

void f(int a=2)
{
}

void f(int a=2);

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;


// mon_template.h
template <class T, template<class, class> class C = std::list>
class Collection
{
T t;
C<int, std::allocator<int> > c;
};


// test1.cpp
# include "mon_fwd.h"

template <class T, template<class, class> class C>
void f(Collection<T, C> &c)
{
// c.whatever();
}


// test2.cpp
# include "mon_template.h"

template <class T, template<class, class> class C>
void f(Collection<T, C> &c)
{
c.whatever();
}


Jonathan

Avatar
Jean-Marc Bourguet
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.

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
Gabriel Dos Reis
Marc Boyer writes:

| 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>

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

| 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...

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 {
// ...
};


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

-- Gaby
Avatar
Jonathan Mcdougall
Grrr...

// mon_template.h
template <class T, template<class, class> class C = std::list>
class Collection
{
T t;
C<int, std::allocator<int> > c;
};


Devrait être

// mon_template.h
template <class T, template<class, class> class C>
class Collection
{
T t;
C<int, std::allocator<int> > c;
};


Jonathan

Avatar
Gabriel Dos Reis
"Jonathan Mcdougall" writes:

| > 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)

std::list prend exactement deux arguments, pas moins, pas plus.

| 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.

| 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.

Bah non, il a été clarifié que ce n'est pas permis.


-- Gaby
Avatar
Gabriel Dos Reis
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.

-- Gaby
1 2 3 4