C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Classes imbriquees, deductabilite, iterateur

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Jean-Marc Bourguet
Guest





PostPosted: Tue Jan 03, 2006 9:49 am    Post subject: Classes imbriquees, deductabilite, iterateur Reply with quote




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





PostPosted: Tue Jan 17, 2006 3:11 pm    Post subject: Re: Classes imbriquees, deductabilite, iterateur Reply with quote



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





PostPosted: Tue Jan 17, 2006 3:17 pm    Post subject: Re: Classes imbriquees, deductabilite, iterateur Reply with quote



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





PostPosted: Tue Jan 17, 2006 3:40 pm    Post subject: Re: Classes imbriquees, deductabilite, iterateur Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.