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 

Comment déclarer friend un paramètre template d'une classe ?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Helfer Thomas
Guest





PostPosted: Wed Jul 19, 2006 2:23 am    Post subject: Comment déclarer friend un paramètre template d'une classe ? Reply with quote



Cette question est liée à l'impossibilité d'écrire le code suivant :

template<class T>
struct Test
{
friend class T;
};

Existerait-il un moyen (détourné) de faire cela ?

Cordialement,

Helfer Thomas
Back to top
Sylvain
Guest





PostPosted: Wed Jul 19, 2006 3:44 am    Post subject: Re: Comment déclarer friend un paramèt re template d'une cla Reply with quote



Helfer Thomas wrote on 18/07/2006 23:23:
Quote:
Cette question est liée à l'impossibilité d'écrire le code suivant :

template<class T
struct Test
{
friend class T;
};

Existerait-il un moyen (détourné) de faire cela ?

je suppose que le /struct/ Test vient du fait qu'en effet avec une
/classe/ template cela ne passe pas (parce que écrit comme cela ça passe
évidemment).

si c'est du cas par cas, vous pouvez forcez la génération du code
template et résoudre l'impossibilité par:

lib:

template<class T>
class Test
{
....
};

code applicatif:

class theT;

class TestTheT : public Test<TheT> {
friend class TheT;
};

Sylvain.
Back to top
Helfer Thomas
Guest





PostPosted: Wed Jul 19, 2006 9:12 am    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote



Le Wed, 19 Jul 2006 00:44:02 +0200, Sylvain a écrit :

Quote:
Helfer Thomas wrote on 18/07/2006 23:23:
Cette question est liée à l'impossibilité d'écrire le code suivant :

template<class T
struct Test
{
friend class T;
};

Existerait-il un moyen (détourné) de faire cela ?

je suppose que le /struct/ Test vient du fait qu'en effet avec une
/classe/ template cela ne passe pas (parce que écrit comme cela ça passe
évidemment).

Non le problème est le même que l'on soit en struct ou en class. De

manière plus précise, le morceau de code écrit plus haut conduit au
message d'erreur suivant (gcc-4.0) :

essai.cxx:15: erreur: using template type parameter «T» after «class»
essai.cxx:15: erreur: déclaration amie ne nomme pas une classe ou une
fonction

Votre proposition est intéressante, mais n'a pas la souplesse du code que
je souhaiterai écrire.

Cordialement,

Helfer Thomas
Back to top
Helfer Thomas
Guest





PostPosted: Wed Jul 19, 2006 9:12 am    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote

Le Tue, 18 Jul 2006 23:23:59 +0200, Helfer Thomas a écrit :

Voici un extrait de la faq du compilateur Comeau qui explique
plus en détails mon soucis :

What's wrong with saying friend class T within a template?
Trying to use a template parameter in a friend is ill-formed:

template <typename T>
class xyz {
friend class T; // ill-formed code
};

According to Section 7.1.5.3 paragraph 2 of Standard C++:

3.4.4 describes how name lookup proceeds for the identifier
in an elaborated-type-specifier. ... If the identifier
resolves to a typedef-name or a template type-parameter,
the elaborated-type-specifier is ill-formed.
[Note: this implies that, within a class template
with a template type-parameter T, the declaration
friend class T;
is ill-formed. ]

The next thing one would try would be:

template <typename T>
class xyz {
friend T;
};

but this form is not allowed either because for friends, according
to 11.4 paragraph 2

An elaborated-type-specifier shall be used in a friend
declaration for a class.

And also from footnote #101:

The class-key of the elaborated-type-specifier is required.

You could also probably try some hackery with typedef, but I
suspect all of these attempts will also be illegal.

Le code que j'aimerai utilisé est donc illegal en C++ standard, d'où la
recherche d'une solution détournée...

Merci pour votre aide

Cordialement,

Helfer Thomas



Quote:
Cette question est liée à l'impossibilité d'écrire le code suivant :

template<class T
struct Test
{
friend class T;
};

Existerait-il un moyen (détourné) de faire cela ?

Cordialement,

Helfer Thomas
Back to top
kanze
Guest





PostPosted: Wed Jul 19, 2006 9:12 am    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote

Sylvain wrote:
Quote:
Helfer Thomas wrote on 18/07/2006 23:23:
Cette question est liée à l'impossibilité d'écrire le code suivant :

template<class T
struct Test
{
friend class T;
};

Existerait-il un moyen (détourné) de faire cela ?

je suppose que le /struct/ Test vient du fait qu'en effet avec
une /classe/ template cela ne passe pas (parce que écrit comme
cela ça passe évidemment).

Tu pourrais t'expliquer. Parce que je ne vois pas la moindre
différence entre struct et class ici.

Le code est illégal, c'est sûr. (Je ne serais pas étonné qu'il y
ait une proposition pour résoudre le problème dans la prochaine
version de la norme. Mais ça n'aide pas dans l'immédiat.)

A priori, je ne connais pas de bon work-around, à part rendre
tous les membres de Test public (ce qui permettrait, évidemment,
à classe T d'y accéder, mais aussi à toutes les autres classes).
La plus proche que je peux penser, c'est d'écrire une deuxième
classe template, TestAccessor, de le déclarer comme ami de Test,
et lui pourvoir avec les fonctions (protegées) qui effectuent
tous les accès nécessaire. Aussi, on ne lui donne que un
constructeur protégé, et on utilise des contraints pour assurer
que T dérive de lui. (Est-ce qu'on pourrait s'assurer d'une
façon statique qu'aucune autre classe dérive de lui ?) Quelque
chose du genre :

template< typename T >
class TestAccessor ;

template< typename T >
class Test
{
friend class TestAccessor< T > ;

int i ;
// ...
} ;

template< typename T >
class TestAccessor : boost::noncopiable
{
protected:
int& testI( Test< T >* p ) {
assert( dynamic_cast< T* >( this ) != NULL ) ;
return p->i ;
}
// ...

TestAccessor()
{
T* p = static_cast< T* >( this ) ;
}
} ;

Ça exige que T dérive de TestAccessor<T>, et est contournable,
mais ça doit éviter les accès accidentaux.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Arnaud Meurgues
Guest





PostPosted: Wed Jul 19, 2006 7:57 pm    Post subject: Re: Comment déclarer friend un paramètr e template d'une cla Reply with quote

Gabriel Dos Reis wrote:

Merci d'avoir insisté...

Quote:
template<class T
struct Test
{
friend T;
};

Note l'absence de « class. »

Pourquoi pas class ?
Parce que aucun autre identifieur ne serait valable qu'une fonction qui
serait reconnaissable ?
Ou bien parce que le
template <class T>
a déjà précisé que T était une classe ?
Ou pour une autre raison sioux qui m'échappe ?

--
Arnaud
Back to top
Arnaud Meurgues
Guest





PostPosted: Wed Jul 19, 2006 8:29 pm    Post subject: Re: Comment déclarer friend un paramètr e template d'une cla Reply with quote

Gabriel Dos Reis wrote:

Quote:
Parce que le « class » dans « friend class T » dit vraiment que T est
une classe (i.e. quelque déclarée avec « class » ou « struct. »)
[...]
le « class » dans « template<class T> » est la même chose que
« typename », ce qui est différent.

Parfois, je me demande pourquoi j'aime le C++... ;-)

--
Arnaud
Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Jul 19, 2006 8:59 pm    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote

On Wed, 19 Jul 2006 17:29:57 +0200, Arnaud Meurgues
<news.arnaud (AT) meurgues (DOT) non.fr.invalid>:

Quote:
Parfois, je me demande pourquoi j'aime le C++... Wink

N'est-ce pas Winston Churchill qui a dit "Le C++ est le pire des
langages, à l'exception de tous les autres" ?
Back to top
Laurent Deniau
Guest





PostPosted: Wed Jul 19, 2006 9:21 pm    Post subject: Re: Comment déclarer friend un paramètr e template d'une cla Reply with quote

Gabriel Dos Reis wrote:
Quote:
Arnaud Meurgues <news.arnaud (AT) meurgues (DOT) non.fr.invalid> writes:

| Gabriel Dos Reis wrote:
|
| > Parce que le « class » dans « friend class T » dit vraiment que T est
| > une classe (i.e. quelque déclarée avec « class » ou « struct. »)
| [...]
| > le « class » dans « template<class T> » est la même chose que
| > « typename », ce qui est différent.
|
| Parfois, je me demande pourquoi j'aime le C++... ;-)

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1520.pdf
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1616.pdf
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1722.pdf
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1791.pdf

vous avez pas les memes au format patch ou un cvs qqpart? ;-)

a+, ld.
Back to top
Gabriel Dos Reis
Guest





PostPosted: Wed Jul 19, 2006 9:55 pm    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote

Arnaud Meurgues <news.arnaud (AT) meurgues (DOT) non.fr.invalid> writes:

| Gabriel Dos Reis wrote:
|
| Merci d'avoir insisté...
|
| > template<class T>
| > struct Test
| > {
| > friend T;
| > };
| >
| > Note l'absence de « class. »
|
| Pourquoi pas class ?

Parce que le « class » dans « friend class T » dit vraiment que T est
une classe (i.e. quelque déclarée avec « class » ou « struct. ») Que
se passe-t-il avec

union foo { /* ... */ };

Test<foo> x;

?

| Parce que aucun autre identifieur ne serait valable qu'une fonction qui
| serait reconnaissable ?
| Ou bien parce que le
| template <class T>
| a déjà précisé que T était une classe ?

le « class » dans « template<class T> » est la même chose que
« typename », ce qui est différent.

-- Gaby
Back to top
Gabriel Dos Reis
Guest





PostPosted: Wed Jul 19, 2006 10:06 pm    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote

Arnaud Meurgues <news.arnaud (AT) meurgues (DOT) non.fr.invalid> writes:

| Gabriel Dos Reis wrote:
|
| > Parce que le « class » dans « friend class T » dit vraiment que T est
| > une classe (i.e. quelque déclarée avec « class » ou « struct. »)
| [...]
| > le « class » dans « template<class T> » est la même chose que
| > « typename », ce qui est différent.
|
| Parfois, je me demande pourquoi j'aime le C++... ;-)

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1520.pdf
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1616.pdf
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1722.pdf
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1791.pdf

-- Gaby
Back to top
Sylvain
Guest





PostPosted: Wed Jul 19, 2006 10:59 pm    Post subject: Re: Comment déclarer friend un paramètr e template d'une cla Reply with quote

kanze wrote on 19/07/2006 10:45:
Quote:

template<class T
struct Test
{
friend class T;
};

je suppose que le /struct/ Test vient du fait qu'en effet avec
une /classe/ template cela ne passe pas (parce que écrit comme
cela ça passe évidemment).

Tu pourrais t'expliquer. Parce que je ne vois pas la moindre
différence entre struct et class ici.

"expliquer" c'est dur puisqu'il s'agit d'un code tellemnt réduit qu'il
ne montre pas l'objet même de la question.

déroulons: "friend class T" exprime le fait que la classe "T"
machin-chose (comment dites-vous d'ailleurs?) du template aurait accès
au membres protégés de "Test".

or "Test" est une struct (et non une classe) et donc publie déjà tous
ses membres aux classes amies ou pas, comme à tout bout de code.

second point, Test n'a aucune donnée membre, donc savoir si T sera
suffisamment copain pour accéder à rien est également difficile à commenter.

Sylvain.
Back to top
Gabriel Dos Reis
Guest





PostPosted: Wed Jul 19, 2006 11:17 pm    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote

Laurent Deniau <laurent.deniau (AT) cern (DOT) ch> writes:

| Gabriel Dos Reis wrote:
| > Arnaud Meurgues <news.arnaud (AT) meurgues (DOT) non.fr.invalid> writes:
| > | Gabriel Dos Reis wrote:
| > | | > Parce que le « class » dans « friend class T » dit vraiment
| > que T est
| > | > une classe (i.e. quelque déclarée avec « class » ou « struct. »)
| > | [...]
| > | > le « class » dans « template<class T> » est la même chose que |
| > > « typename », ce qui est différent.
| > | | Parfois, je me demande pourquoi j'aime le C++... Wink
| > http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1520.pdf
| > http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1616.pdf
| > http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1722.pdf
| > http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1791.pdf
|
| vous avez pas les memes au format patch ou un cvs qqpart? ;-)

Je suis persuadé que l'auteur en dispose quelque part :-)

-- Gaby
Back to top
kanze
Guest





PostPosted: Thu Jul 20, 2006 9:11 am    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote

Sylvain wrote:
Quote:
kanze wrote on 19/07/2006 10:45:

template<class T
struct Test
{
friend class T;
};

je suppose que le /struct/ Test vient du fait qu'en effet
avec une /classe/ template cela ne passe pas (parce que
écrit comme cela ça passe évidemment).

Tu pourrais t'expliquer. Parce que je ne vois pas la moindre
différence entre struct et class ici.

"expliquer" c'est dur puisqu'il s'agit d'un code tellemnt
réduit qu'il ne montre pas l'objet même de la question.

C'est sûr que dans l'exemple même, le friend ne pourrait pas
donner accès à grand chose, étant donné que la classe ne
contient pas grand chose.

Quote:
déroulons: "friend class T" exprime le fait que la classe "T"
machin-chose (comment dites-vous d'ailleurs?) du template
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


La classe T. Ou simplement T.

Quote:
aurait accès au membres protégés de "Test".

Je suppose qu'ici, tu entends par « protégé » le sens général
du mot, et non comme traduction du mot clé « protected ».
Friend donne bien accès aussi aux membres « private ».

Quote:
or "Test" est une struct (et non une classe)

« Test » est une classe. Il n'y a pas de « struct » en C++.
Il y a bien un concepte de « POD-struct », et une
instanciation de Test ici serait bien un « POD-struct ». Mais
il me semble évident que la définition ici ne contient que des
parties qui rapporte à la discussion ; dans l'absense de
membre, friend ne sert effectivement à rien. Et dans la mesure
qu'on ne sait rien de ces membres, on ne saurait dire si la
classe réele est une POD-struct ou non.

Quote:
et donc publie déjà tous ses membres aux classes amies ou pas,
comme à tout bout de code.

C'est une convention assez répandue d'utiliser le mot clé struct
pour définir une classe où tous les membres sont publics, et que
pour de telles classes, mais c'est loin d'être une règle.

Quote:
second point, Test n'a aucune donnée membre, donc savoir si T
sera suffisamment copain pour accéder à rien est également
difficile à commenter.

Tout à fait d'accord là. Mais la question tournait uniquement
sur la légalité de la declaration « friend », non sur son
utilité dans le cas précis de l'exemple. Le point que Thomas
faisait, c'est qu'il n'y a aucune façon de faire un paramètre
type d'un template ami de la classe templatée.

(En fait, il y a une tradition d'utiliser le mot-clé struct,
plutôt de class, dans les questions qui concernent
l'interprétation de la norme. Sans doute parce qu'en général, la
question ne concerne pas l'accès, et les spécifications d'accès
n'y serait que du verbiage pour rien.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Helfer Thomas
Guest





PostPosted: Thu Jul 20, 2006 10:33 pm    Post subject: Re: Comment déclarer friend un paramètre template d'une clas Reply with quote

Merci pour vos réponses. Pour répondre à vos questions, j'utilise de
manière indifférente class ou struct. La finalité de la question est
bien sûr que le paramètre template de Test puisse accéder aux données
membres privées/protégées (Oui, je n'en ai pas mis dans l'exemple...).

J'ai trouvé une astuce qui fonctionne avec gcc 4.1. Il s'agit de faire
ceci :

template<typename T>
struct identity
{
typedef T type;
};

template<class T>
struct Test
{
friend class typename identity<T>::type;
};

Cette solution fonctionne. Puis-je attendre qu'elle soit portable ?

Cordialement,

Helfer Thomas

Quote:
Cette question est liée à l'impossibilité d'écrire le code suivant :

template<class T
struct Test
{
friend class T;
};

Existerait-il un moyen (détourné) de faire cela ?

Cordialement,

Helfer Thomas
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
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.