Topic: friend class templates
Author: "Andrei Iltchenko" <iltchenko@yahoo.com>
Date: Wed, 21 Feb 2001 00:01:48 GMT Raw View
Sai Shankar <Sai.Shankar@blr.spcnl.co.in> wrote in message
news:3A8DF943.CB6AC2FA@blr.spcnl.co.in...
>
>
> James Dennett wrote:
>
> [snip quoted stuff for brevity]
>
> > >
> > > template <class T>
> > > struct friend_traits
> > > {
> > > typedef T friend_class;
> > > };
> > >
> > > template <class T>
> > > class A
> > > {
> > > //...
> > >
> > > friend class typename friend_traits<T>::friend_class;
> > > //...
> > > };
> > >
> > > should work.
> >
> > I don't think so. The name still depends on a template argument.
> > Am I missing the point?
>
> Probably not, because after reading the Standard, I'm still unclear as
> to whether this is valid or not.
>
> However, could someone point to specific sections of the Standard which
> make this wrong?
11.4/4 says "An elaborated-type specifier shall be used in a friend
declaration for a class. [footnote] The class-key of the elaborated type
specifier is required."
The current version of the Standard defines the syntax for an
elaborated-type-specifier in the following way:
elaborated-type-specifier:
class-key :: opt nested-name-specifier opt identifier (*)
enum :: opt nested-name-specifier opt identifier
typename :: opt nested-name-specifier identifier
typename :: opt nested-name-specifier template opt template-id
Given the requirements of 11.4/4, only the form marked with (*) can be used
in a friend declaration of a class. And this form doesn't provide for the
use of the typename keyword.
> template <class T>
> class A
> {
> //...
>
> friend class typename friend_traits<T>::friend_class;
In this context typename is required (See 14.6), as
'friend_traits<T>::friend_class' is a dependent type, but the syntax doesn't
allow for this.
> And also specify the rationale for this?
I have no idea.
> I seem to remember a DR on this issue.
The only one that I came across and which has something in common with the
discussion is this:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#68
But it is more concerned with the syntax for an elaborated-type-specifier
than with whether a dependent type can be used in a friend class declaration
or not. Note that the proposed resolution for that DR also disallows for
your construct.
Regards,
Andrei Iltchenko
Brainbench MVP for C++
http://www.brainbench.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Sai Shankar <Sai.Shankar@blr.spcnl.co.in>
Date: Wed, 21 Feb 2001 17:26:33 GMT Raw View
Heinz Huber wrote:
>
[snip]
> > > template <class T> class A
> > > {
> > > friend T;
> > > }
> > >
> > > We could now supply a class for template parameter T that reads out all
> > > of A's internals or does some other bad stuff with A.
> >
> > That's what 'friend' means. If that's what the programmer is explicitly
> > saying he wants, why prohibit it?
>
> The difference is that without a template you explicitly name the
> friend. And friendship is not inherited. Therefore, you exactly know,
> who your friend is. And normally also what it does, since such tightly
> coupled classes tend to be developed together (at least in my opinion).
Friendship would not be inherited or transitive here either.
> If the supposed friend depends on a template parameter, you don't know
> anything about it. Therefore you totally give up control of your class
> and it's internals, since a malign friend can really screw up the
> instance. Again that's not such a problem in case of normal friends,
> because you know them and can still control what they're doing.
Only for the instantiation of the template.
So if i write/use struct A { }; and I get a
template <class T> struct B { friend class T; }
and instantiate it with class A, I am only getting access to B<A> from A,
which should be OK, since I am the writer/user of A.
"Protect against Murphy, not Machiavelli" comes to mind.
Even if it were otherwise, as the template writer, I am prepared to take
the risk. Why should the language make it not possible, especially as it
seems to involve no efficiency costs?
Just my thoughts.
Regards
Sai Shankar
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Sai Shankar <Sai.Shankar@blr.spcnl.co.in>
Date: Fri, 16 Feb 2001 08:27:39 GMT Raw View
Martin Sebor wrote:
>
> Stefan Schwarzer wrote:
> >
> > I have a syntax question.
> >
> > According to 14.5.3.1 a class template may have friends, including
> > function and class templates, specializations thereof, and ordinary
> > functions or classes. I would like to declare as friend (in my case)
> > an ordinary class, given in terms of a template parameter:
> >
> >
> > template <class T>
> > class A {
> > // what am I supposed to write here if I want to declare T friend?
> > // (i) friend class T;
> > // (ii) friend T;
> > };
>
> It would be nice if you could do that, but...
>
And an easy way to do what you require is:
template <class T>
struct friend_traits
{
typedef T friend_class;
};
template <class T>
class A
{
//...
friend class typename friend_traits<T>::friend_class;
//...
};
should work.
However, be warned. None of the three compilers i tested with actually
managed to compile the code.
GNU C++ got closest and compiled when i removed the typename.
For Borland C++ (V 5.5) and VC++ users (VC6 SP3), the following works:
template <class T>
struct A
{
//...
friend class T;
//...
};
Hope this helps...
Rgds,
Sai Shankar.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: James Dennett <jdennett@acm.org>
Date: Fri, 16 Feb 2001 21:52:59 GMT Raw View
Sai Shankar wrote:
>
> Martin Sebor wrote:
> >
> > Stefan Schwarzer wrote:
> > >
> > > I have a syntax question.
> > >
> > > According to 14.5.3.1 a class template may have friends, including
> > > function and class templates, specializations thereof, and ordinary
> > > functions or classes. I would like to declare as friend (in my case)
> > > an ordinary class, given in terms of a template parameter:
> > >
> > >
> > > template <class T>
> > > class A {
> > > // what am I supposed to write here if I want to declare T friend?
> > > // (i) friend class T;
> > > // (ii) friend T;
> > > };
> >
> > It would be nice if you could do that, but...
> >
> And an easy way to do what you require is:
>
> template <class T>
> struct friend_traits
> {
> typedef T friend_class;
> };
>
> template <class T>
> class A
> {
> //...
>
> friend class typename friend_traits<T>::friend_class;
> //...
> };
>
> should work.
I don't think so. The name still depends on a template argument.
Am I missing the point?
> However, be warned. None of the three compilers i tested with actually
> managed to compile the code.
I think they're right to reject it.
-- James Dennett <jdennett@acm.org>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Sai Shankar <Sai.Shankar@blr.spcnl.co.in>
Date: Sat, 17 Feb 2001 22:58:19 GMT Raw View
James Dennett wrote:
[snip quoted stuff for brevity]
> >
> > template <class T>
> > struct friend_traits
> > {
> > typedef T friend_class;
> > };
> >
> > template <class T>
> > class A
> > {
> > //...
> >
> > friend class typename friend_traits<T>::friend_class;
> > //...
> > };
> >
> > should work.
>
> I don't think so. The name still depends on a template argument.
> Am I missing the point?
Probably not, because after reading the Standard, I'm still unclear as
to whether this is valid or not.
However, could someone point to specific sections of the Standard which
make this wrong? And also specify the rationale for this? I seem to
remember a DR on this issue.
I think that the Standard is in error here. This is a very useful construct
to have and it is difficult to understand why this is disallowed!
Regards
Sai Shankar
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Heinz Huber <Heinz.Huber@elbanet.co.at>
Date: Mon, 19 Feb 2001 17:05:41 GMT Raw View
Sai Shankar wrote:
>
> James Dennett wrote:
>
> [snip quoted stuff for brevity]
>
> > >
> > > template <class T>
> > > struct friend_traits
> > > {
> > > typedef T friend_class;
> > > };
> > >
> > > template <class T>
> > > class A
> > > {
> > > //...
> > >
> > > friend class typename friend_traits<T>::friend_class;
> > > //...
> > > };
> > >
> > > should work.
> >
> > I don't think so. The name still depends on a template argument.
> > Am I missing the point?
>
> Probably not, because after reading the Standard, I'm still unclear as
> to whether this is valid or not.
>
> However, could someone point to specific sections of the Standard which
> make this wrong? And also specify the rationale for this? I seem to
> remember a DR on this issue.
>
> I think that the Standard is in error here. This is a very useful construct
> to have and it is difficult to understand why this is disallowed!
I can't quote the standard on anything in this regard, but I can give a
good rationale for disallowing any type depending on a template
parameter for a friend declaration.
Take the original (wanted) definition:
template <class T> class A
{
friend T;
}
We could now supply a class for template parameter T that reads out all
of A's internals or does some other bad stuff with A.
I think this is reason enough not to allow this kind of construct.
hth,
Heinz
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 19 Feb 2001 19:13:44 GMT Raw View
Heinz Huber wrote:
...
> I can't quote the standard on anything in this regard, but I can give a
> good rationale for disallowing any type depending on a template
> parameter for a friend declaration.
> Take the original (wanted) definition:
> template <class T> class A
> {
> friend T;
> }
>
> We could now supply a class for template parameter T that reads out all
> of A's internals or does some other bad stuff with A.
That's what 'friend' means. If that's what the programmer is explicitly
saying he wants, why prohibit it?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Heinz Huber <Heinz.Huber@elbanet.co.at>
Date: Tue, 20 Feb 2001 13:59:52 GMT Raw View
"James Kuyper Jr." wrote:
>
> Heinz Huber wrote:
> ...
> > I can't quote the standard on anything in this regard, but I can give a
> > good rationale for disallowing any type depending on a template
> > parameter for a friend declaration.
> > Take the original (wanted) definition:
> > template <class T> class A
> > {
> > friend T;
> > }
> >
> > We could now supply a class for template parameter T that reads out all
> > of A's internals or does some other bad stuff with A.
>
> That's what 'friend' means. If that's what the programmer is explicitly
> saying he wants, why prohibit it?
The difference is that without a template you explicitly name the
friend. And friendship is not inherited. Therefore, you exactly know,
who your friend is. And normally also what it does, since such tightly
coupled classes tend to be developed together (at least in my opinion).
If the supposed friend depends on a template parameter, you don't know
anything about it. Therefore you totally give up control of your class
and it's internals, since a malign friend can really screw up the
instance. Again that's not such a problem in case of normal friends,
because you know them and can still control what they're doing.
Regards,
Heinz
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Stefan Schwarzer <sts@tiger.ica1.uni-stuttgart.de>
Date: Mon, 12 Feb 2001 17:05:09 GMT Raw View
I have a syntax question.
According to 14.5.3.1 a class template may have friends, including
function and class templates, specializations thereof, and ordinary
functions or classes. I would like to declare as friend (in my case)
an ordinary class, given in terms of a template parameter:
template <class T>
class A {
// what am I supposed to write here if I want to declare T friend?
// (i) friend class T;
// (ii) friend T;
};
Given no further assistence by the examples in 14.5.3, I tried to
deduce possible forms from the grammar rules in the appendix (I have no
formal computer science background, so I apologize for misunderstandings).
What one finds in the section about 'declarations'
seems to indicate that both 'friend class T' and 'friend T' are
grammatically ok, if T is (in particular) an 'identifier' which it seems
to be from the rules for template argument lists.
One problem I can see is that T at the point of instantiation is not
actually the 'identifier' required for a class name, but say, a simple
type like 'int'. But then, there are many other cases of where the
correctness of a program depends on templates being instantiated with
the 'proper' types, as discussed later in the standard, for example in
conjunction with dependend types.
I am using KCC 4.0 and gcc-2.95.2; both compilers reject (i)
(even without instantiation attempt), g++ -pedantic accepts (ii), KCC
complains that omission of "class" be nonstandard.
Can anyone enlighten me about the correct/intended syntax or whether I
overlook some other provision of the standard?
Thanks a lot,
Stefan.
--
Stefan Schwarzer office: +49-(0)711-685-7606 fax: x-3658
Uni Stuttgart, ICA 1 (?-
Pfaffenwaldring 27 //\ sts@ica1.uni-stuttgart.de
70569 Stuttgart, Germany -V_/---- http://www.ica1.uni-stuttgart.de/~sts
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Martin Sebor <sebor@roguewave.com>
Date: Tue, 13 Feb 2001 15:19:26 GMT Raw View
Stefan Schwarzer wrote:
>
> I have a syntax question.
>
> According to 14.5.3.1 a class template may have friends, including
> function and class templates, specializations thereof, and ordinary
> functions or classes. I would like to declare as friend (in my case)
> an ordinary class, given in terms of a template parameter:
>
>
> template <class T>
> class A {
> // what am I supposed to write here if I want to declare T friend?
> // (i) friend class T;
> // (ii) friend T;
> };
It would be nice if you could do that, but...
7.1.5.3, p2: basic.lookup.elab describes how name lookup proceeds for the
identifier in an elaborated-type-specifier. If the identifier resolves to a
class-name or enum-name, the elaborated-type-specifier introduces it into the
declaration the same way a simple-type-specifier introduces its type-name. 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. ] If name lookup does not find a declaration for the name, the
elaborated-type-specifier is ill-formed unless it is of the simple form
class-key identifier in which case the identifier is declared as described in
basic.scope.pdecl.
See also http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#245.
Regards
Martin
>
> Given no further assistence by the examples in 14.5.3, I tried to
> deduce possible forms from the grammar rules in the appendix (I have no
> formal computer science background, so I apologize for misunderstandings).
> What one finds in the section about 'declarations'
> seems to indicate that both 'friend class T' and 'friend T' are
> grammatically ok, if T is (in particular) an 'identifier' which it seems
> to be from the rules for template argument lists.
>
> One problem I can see is that T at the point of instantiation is not
> actually the 'identifier' required for a class name, but say, a simple
> type like 'int'. But then, there are many other cases of where the
> correctness of a program depends on templates being instantiated with
> the 'proper' types, as discussed later in the standard, for example in
> conjunction with dependend types.
>
> I am using KCC 4.0 and gcc-2.95.2; both compilers reject (i)
> (even without instantiation attempt), g++ -pedantic accepts (ii), KCC
> complains that omission of "class" be nonstandard.
>
> Can anyone enlighten me about the correct/intended syntax or whether I
> overlook some other provision of the standard?
>
> Thanks a lot,
>
> Stefan.
>
> --
> Stefan Schwarzer office: +49-(0)711-685-7606 fax: x-3658
> Uni Stuttgart, ICA 1 (?-
> Pfaffenwaldring 27 //\ sts@ica1.uni-stuttgart.de
> 70569 Stuttgart, Germany -V_/---- http://www.ica1.uni-stuttgart.de/~sts
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> [ Note that the FAQ URL has changed! Please update your bookmarks. ]
======================================= MODERATOR'S COMMENT:
Please don't overquote.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]