 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Jean-Marc Bourguet Guest
|
Posted: Tue Jan 03, 2006 9:49 am Post subject: Classes imbriquees, deductabilite, iterateur |
|
|
Dans un vieux message, Gabriel me repondait:
| Quote: | C'est une vieille disussion : si conteneur<type>::iterator est
réellement une classe imbriquée alors souvent type sera dans un
contexte non déductible. James en avait fait l'expérience, je crois.
C'est des exemples de contextes que je voudrais.
Cela arrive quand les gens veulent écrire des fonctions templates,
en exprimant la contrainte que la classe est vraiment imbriquée dans
une certaine classe donnée, par exemple ils veulent que leurs
fonctions opèrent sur un vector<T>::iterator et pas sur un
list<T>::iterator. Alors, typiquement ils vont exprimer la contrainte
comme cela ; évidemment cela ne marche pas.
template<class T
struct vector {
struct iterator { /* ... */ };
// ...
};
template
struct list {
struct iterator { /* ... */ };
// ...
};
template
void sort(typename vector
Ou, cela peut être aussi des contraintes sur le T, i.e. distinguer un
T* d'un U...
En général, j'utilise quand même les classes imbriquées dans les
templates. J'exprime les contraintes différemment -- et cela demande
un peu plus de travail mais on peut vivrte avec.
|
Il me semble que le probleme doit exister aussi si iterator n'est pas
une classe imbriquee mais un typedef vers une classe externe. En tout
cas les compilateurs que j'ai essaie (como online, g++ 4.0.2, Sun C++
5.7 Patch 117830-03 2005/07/21) ont tous le meme comportement sur le
code:
template <typename T>
class Container1 {
public:
class iterator {
};
};
template <typename T>
class Container2Iterator {
};
template <typename T>
class Container2 {
public:
typedef Container2Iterator<T> iterator;
};
template <typename T>
void f1(typename Container1<T>::iterator) {
}
template <typename T>
void f2(typename Container2<T>::iterator) {
}
template <typename T>
void f2bis(Container2Iterator<T>) {
}
void f() {
Container1<int>::iterator i1;
Container2<int>::iterator i2;
f1(i1);
f2(i2);
f2bis(i2);
}
f1 et f2 ne passent pas et f2bis passe.
Sachant qu'on veut utiliser l'interface C<T>::iterator, y a-t'il un
avantage intrinseque quelconque a utiliser l'une forme ou l'autre ?
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
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Jan 17, 2006 3:11 pm Post subject: Re: Classes imbriquees, deductabilite, iterateur |
|
|
Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> writes:
| Quote: | Dans un vieux message, Gabriel me repondait:
C'est une vieille disussion : si conteneur<type>::iterator est
réellement une classe imbriquée alors souvent type sera dans un
contexte non déductible. James en avait fait l'expérience, je crois.
C'est des exemples de contextes que je voudrais.
Cela arrive quand les gens veulent écrire des fonctions templates,
en exprimant la contrainte que la classe est vraiment imbriquée dans
une certaine classe donnée, par exemple ils veulent que leurs
fonctions opèrent sur un vector<T>::iterator et pas sur un
list<T>::iterator. Alors, typiquement ils vont exprimer la contrainte
comme cela ; évidemment cela ne marche pas.
template<class T
struct vector {
struct iterator { /* ... */ };
// ...
};
template
struct list {
struct iterator { /* ... */ };
// ...
};
template
void sort(typename vector
Ou, cela peut être aussi des contraintes sur le T, i.e. distinguer un
T* d'un U...
En général, j'utilise quand même les classes imbriquées dans les
templates. J'exprime les contraintes différemment -- et cela demande
un peu plus de travail mais on peut vivrte avec.
Il me semble que le probleme doit exister aussi si iterator n'est pas
une classe imbriquee mais un typedef vers une classe externe.
|
Oui, tu as raison. La notion exacte est « nested types » et pas juste
class imbriquée -- car elle englobe bien les classes imbriquees et les
typedefs définis à l'intérieur d'une classe.
| Quote: | En tout
cas les compilateurs que j'ai essaie (como online, g++ 4.0.2, Sun C++
5.7 Patch 117830-03 2005/07/21) ont tous le meme comportement sur le
code:
template <typename T
class Container1 {
public:
class iterator {
};
};
template
class Container2Iterator {
};
template
class Container2 {
public:
typedef Container2Iterator
};
template <typename T
void f1(typename Container1
}
template <typename T
void f2(typename Container2
}
template <typename T
void f2bis(Container2Iterator
}
void f() {
Container1<int>::iterator i1;
Container2<int>::iterator i2;
f1(i1);
f2(i2);
f2bis(i2);
}
f1 et f2 ne passent pas et f2bis passe.
Sachant qu'on veut utiliser l'interface C<T>::iterator, y a-t'il un
avantage intrinseque quelconque a utiliser l'une forme ou l'autre ?
|
si tu as des garanties que C<T>::iterator sera toujours
Container2<T>::iterator, alors va pour f2bis. Mais si tu veux
enforcer cette contrainte, je ne vois que deux solutions pour le
moment :
(1) SFINAE hackery ;
(2) parametrer l'itérateur par le container (un peu comme nous
l'avons fait pour std::vector<T>::iterator pour le distinguer
d'un pointeur brut).
template<class Container>
struct Iterator { ... };
ou
template<template
struct Iterator { ... };
-- Gaby
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Tue Jan 17, 2006 3:17 pm Post subject: Re: Classes imbriquees, deductabilite, iterateur |
|
|
Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> writes:
| Quote: | Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> writes:
| Dans un vieux message, Gabriel me repondait:
|
| > > > C'est une vieille disussion : si conteneur<type>::iterator est
| > > > réellement une classe imbriquée alors souvent type sera dans un
| > > > contexte non déductible. James en avait fait l'expérience, je crois.
|
| > > C'est des exemples de contextes que je voudrais.
|
| > Cela arrive quand les gens veulent écrire des fonctions templates,
| > en exprimant la contrainte que la classe est vraiment imbriquée dans
| > une certaine classe donnée, par exemple ils veulent que leurs
| > fonctions opèrent sur un vector<T>::iterator et pas sur un
| > list<T>::iterator. Alors, typiquement ils vont exprimer la contrainte
| > comme cela ; évidemment cela ne marche pas.
|
| > template<class T
| > struct vector {
| > struct iterator { /* ... */ };
| > // ...
| > };
|
| > template<class T
| > struct list {
| > struct iterator { /* ... */ };
| > // ...
| > };
|
| > template<class T
| > void sort(typename vector<T>::iterator f, typename vector<T>::iterator l);
|
| > Ou, cela peut être aussi des contraintes sur le T, i.e. distinguer un
| > T* d'un U...
|
| > En général, j'utilise quand même les classes imbriquées dans les
| > templates. J'exprime les contraintes différemment -- et cela demande
| > un peu plus de travail mais on peut vivrte avec.
|
| Il me semble que le probleme doit exister aussi si iterator n'est pas
| une classe imbriquee mais un typedef vers une classe externe.
Oui, tu as raison. La notion exacte est « nested types » et pas juste
class imbriquée -- car elle englobe bien les classes imbriquees et les
typedefs définis à l'intérieur d'une classe.
| En tout
| cas les compilateurs que j'ai essaie (como online, g++ 4.0.2, Sun C++
| 5.7 Patch 117830-03 2005/07/21) ont tous le meme comportement sur le
| code:
|
| template <typename T
| class Container1 {
| public:
| class iterator {
| };
| };
|
| template
| class Container2Iterator {
| };
|
| template
| class Container2 {
| public:
| typedef Container2Iterator
| };
|
| template <typename T
| void f1(typename Container1
| }
|
| template <typename T
| void f2(typename Container2
| }
|
| template <typename T
| void f2bis(Container2Iterator
| }
|
| void f() {
| Container1<int>::iterator i1;
| Container2<int>::iterator i2;
|
| f1(i1);
| f2(i2);
| f2bis(i2);
| }
|
| f1 et f2 ne passent pas et f2bis passe.
|
| Sachant qu'on veut utiliser l'interface C<T>::iterator, y a-t'il un
| avantage intrinseque quelconque a utiliser l'une forme ou l'autre ?
si tu as des garanties que C<T>::iterator sera toujours
Container2<T>::iterator, alors va pour f2bis.
|
Je me suis mal exprime. J'etais du point de vue de celui qui ecrit
Container. Est-ce qu'utiliser la methode de Container1 ou celle de
Container2 apporte quelque chose aux utilisateurs? J'avais tendance a
utiliser celle de Container2 parce qu'avais conclu que oui par erreur
suite a ce thread. Maintenant il me semble que pour l'utilisateur le
choix est indifferent.
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
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Jan 17, 2006 3:40 pm Post subject: Re: Classes imbriquees, deductabilite, iterateur |
|
|
Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> writes:
[...]
| Quote: | | En tout
| cas les compilateurs que j'ai essaie (como online, g++ 4.0.2, Sun C++
| 5.7 Patch 117830-03 2005/07/21) ont tous le meme comportement sur le
| code:
|
| template <typename T
| class Container1 {
| public:
| class iterator {
| };
| };
|
| template
| class Container2Iterator {
| };
|
| template
| class Container2 {
| public:
| typedef Container2Iterator
| };
|
| template <typename T
| void f1(typename Container1
| }
|
| template <typename T
| void f2(typename Container2
| }
|
| template <typename T
| void f2bis(Container2Iterator
| }
|
| void f() {
| Container1<int>::iterator i1;
| Container2<int>::iterator i2;
|
| f1(i1);
| f2(i2);
| f2bis(i2);
| }
|
| f1 et f2 ne passent pas et f2bis passe.
|
| Sachant qu'on veut utiliser l'interface C<T>::iterator, y a-t'il un
| avantage intrinseque quelconque a utiliser l'une forme ou l'autre ?
si tu as des garanties que C<T>::iterator sera toujours
Container2<T>::iterator, alors va pour f2bis.
Je me suis mal exprime. J'etais du point de vue de celui qui ecrit
Container. Est-ce qu'utiliser la methode de Container1 ou celle de
Container2 apporte quelque chose aux utilisateurs?
|
aucun bénéfice qui me saute aux yeux.
| Quote: | J'avais tendance a
utiliser celle de Container2 parce qu'avais conclu que oui par erreur
suite a ce thread. Maintenant il me semble que pour l'utilisateur le
choix est indifferent.
|
désolé d'avoir causé la confusion par l'utilisation de termes trop
restrictifs.
On peut arguer que la méthode Container1 encapsule « plus », mais je
ne sais pas si c'est un argument décisif.
-- Gaby
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|