Topic: Anyone know WHY template parameter cannot be declared friend
Author: mlock@online.ru (Maxim Locktyukhin)
Date: 29 Apr 2003 05:30:18 -0400 Raw View
> pavel_vozenilek@yahoo.co.uk (Pavel Vozenilek) wrote in message
> ksvap@yahoo.com (Stas Kondratiev) wrote in message
> >I don't know if it's a BUG or a FEATURE in MS VC++ 6/7 ('cos I couldnt
> > find any info in MSDN), but this compilers allow the following syntax:
> >
> > template <class T>
> > class A
> > {
> > friend T;
> > void f() {}
> > };
> >
> >
> It is bug. Some other compilers have such a bug too.
Bug or not, but I like it and use it. It is most desired behaviour I
think. What problem it could cause? Why (and in what part ;) )standard
does now allow this?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: rmaddox@isicns.com (Randy Maddox)
Date: 30 Apr 03 07:39:10 GMT Raw View
mlock@online.ru (Maxim Locktyukhin) wrote in message news:<356b1096.0304280633.59da9ff0@posting.google.com>...
> > pavel_vozenilek@yahoo.co.uk (Pavel Vozenilek) wrote in message
> > ksvap@yahoo.com (Stas Kondratiev) wrote in message
> > >I don't know if it's a BUG or a FEATURE in MS VC++ 6/7 ('cos I couldnt
> > > find any info in MSDN), but this compilers allow the following syntax:
> > >
> > > template <class T>
> > > class A
> > > {
> > > friend T;
> > > void f() {}
> > > };
> > >
> > >
> > It is bug. Some other compilers have such a bug too.
>
> Bug or not, but I like it and use it. It is most desired behaviour I
> think. What problem it could cause? Why (and in what part ;) )standard
> does now allow this?
> ---
What problem and why? See John Spicer's earlier posts to this thread
for a thorough discussion. What part of the standard? 7.1.5.3, para
2.
Randy.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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. --- ]
Author: Hyman Rosen <hyrosen@mail.com>
Date: 28 Apr 03 07:07:46 GMT Raw View
Allan W wrote:
> Slightly more typing -- but same net effect as the illegal template
> version.
Well, sure. But the point of templates is to eliminate the
need to type the same code repeatedly while just varying a
type parameter, so inasmuch as they do not work for this
case, it is a defect in the template mechanism.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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. --- ]
Author: pavel_vozenilek@yahoo.co.uk (Pavel Vozenilek)
Date: 28 Apr 03 07:08:18 GMT Raw View
ksvap@yahoo.com (Stas Kondratiev) wrote in message news:<c8453310.0304070736.1917df9a@posting.google.com>...
> I don't know if it's a BUG or a FEATURE in MS VC++ 6/7 ('cos I couldnt
> find any info in MSDN), but this compilers allow the following syntax:
>
> template <class T>
> class A
> {
> friend T;
> void f() {}
> };
>
>
It is bug. Some other compilers have such a bug too.
/Pavel
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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. --- ]
Author: rmaddox@isicns.com (Randy Maddox)
Date: 28 Apr 2003 15:04:03 -0400 Raw View
pavel_vozenilek@yahoo.co.uk (Pavel Vozenilek) wrote in message news:<731020ca.0304261851.fb65530@posting.google.com>...
> ksvap@yahoo.com (Stas Kondratiev) wrote in message news:<c8453310.0304070736.1917df9a@posting.google.com>...
> > I don't know if it's a BUG or a FEATURE in MS VC++ 6/7 ('cos I couldnt
> > find any info in MSDN), but this compilers allow the following syntax:
> >
> > template <class T>
> > class A
> > {
> > friend T;
> > void f() {}
> > };
> >
> >
> It is bug. Some other compilers have such a bug too.
>
> /Pavel
>
Ooops! Sorry. Incorrect. See John Spicer's postings to this thread
on April 4 and April 20 for details. See also subclause 7.1.5.3, para
2, where this usage is explicitly mentioned as being ill-formed.
Which is probably why other compilers have the same "bug". :-)
Randy.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: "John H. Spicer" <jhs@edg.com>
Date: 20 Apr 2003 06:48:14 -0400 Raw View
HumptyDumpty wrote:
> Hi all, does anyone know WHY template parameters cannot be declared friend
> of a template class, i.e.
>
> template <class T>
> struct Foo {
> friend class T;
> };
>
> is invalid according to the Standard. I can't see what's wrong with such
> declaration.
>
> Thanks,
> Oliver
I posted a reply to this a couple of weeks ago, but the message that appeared in
the newsgroups had nothing to do with what I submitted, so I'll try again.
Hope it makes it this time.
John.
Previously posted message:
The following is something I posted to the standard committee's reflector last
September on this subject.
John Spicer
Edison Design Group
-------------------------------------------------------------------------
Whether or not "friend class T" should be permitted was discussed
in San Jose in November of 1993, where it was agreed that this should
be permitted.
Then in Waterloo, in July of 1994 we reopened the issue to address
cases like this:
template <class T> void f(struct T t){}
template <class T> void f(union T t){}
template <class T> void f(enum T t){}
union U {};
struct S {};
class C {};
enum E {};
int main()
{
U u;
S s;
C c;
E e;
f(u);
f(s);
f(c);
f(e);
}
The issue being whether or not you can choose a function template based
on the kind of elaborated type specifier that is present (something actually
supported by the EDG front end back in those days). The committee decided
against this, and as a result, a rule was added prohibiting a template
parameter from being used in an elaborated type specifier in a function
template declaration.
At the infamous Santa Cruz meeting in March of 1996 the issue was raised
again. The text below is from version 15 of my template issues paper
and covers the discussion in Santa Cruz.
So, it would be possible to simply permit "friend class T", but we'd have
to make sure that we address related issues like the ones raised in
Santa Cruz.
---------------------------------------------------------------------------
From my template issues paper (version 15)
3.28 Elaborated type specifiers in function template declarations revisited.
In Waterloo, we decided that an elaborated type specifier containing a
template parameter name could not be used in a function template declaration.
Now that we have the partial ordering rules for function templates,
this issue should be checked to see if it is still what we want.
With the partial ordering rules, we can now select one template over another
based on one being ``more specialized'' than another. It seems that these
rules could be applied to elaborated type specifiers as well.
If this is permitted in the partial ordering of function templates, it should
also be permitted in the partial ordering used for class template partial
specializations.
template <class T> class List {};
template <class T> void f(List<struct T> l){} // #1
template <class T> void f(List<union T> l){} // #2
template <class T> void f(List<enum T> l){} // #3
template <class T> void f(List<T> l){} // #3
union U {};
struct S {};
class C {};
enum E {};int main()
{
List<U> u;
List<S> s;
List<C> c;
List<E> e;
List<int> i;
f(u); // calls #2
f(s); // calls #1
f(c); // calls #1
f(e); // calls #3
f(i); // calls #4
}
Answer:
Core-3 decided that the current rule banning use of template parameters
in elaborated type specifiers only in function template declarations
was not sufficient (because of things like partial specializations of
classes), and that a simple prohibition against the use of template
parameters in elaborated type specifiers was more desirable than
a more complicated rule.
Consequently, template parameters cannot be used in elaborated type specifiers.
---------------------------------------------------------------------------
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Hyman Rosen <hyrosen@mail.com>
Date: 21 Apr 03 02:10:14 GMT Raw View
Ron wrote:
> It's debatable whether a language should or should not encourage
> quality design.
Languages should make good programs possible, not bad programs
impossible. (Not original with me.)
> You could work around it, though, simply by omitting no_children
> and declaring bachelor's constructor(s) to be private.
No, because I want bachelor to be constructible by anyone.
I just want to make any classes derived from bachelor not be
constructible.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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. --- ]
Author: rcrane@ictv.com (Ron)
Date: 19 Apr 2003 05:47:38 -0400 Raw View
> Ron wrote:
> > In the sense of "would it work?", nothing's wrong with it. However,
> > it's not a Good Thing (strong coupling and all), and there are other,
> > better ways to do what you want.
>
> Strong coupling is irrelevant, because we're talking about
> permitted expression within the language, not quality of
> design.
It's debatable whether a language should or should not encourage
quality design. I'm not taking either side of that issue, but merely
speculating on why template-argument friends aren't allowed by the
Standard.
> As for better ways, how do you do the "don't derive
> from me" pattern? We want to say
>
> template <typename T> class no_children {
> no_children() { }
> friend class T;
> };
> class bachelor : virtual no_children<bachelor> { };
Hmm, a good point: without template-argument friends, bachelor can't
call no_children's constructor. You could work around it, though,
simply by omitting no_children and declaring bachelor's constructor(s)
to be private.
-- Ron
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: 23 Apr 2003 15:11:43 -0400 Raw View
Hyman Rosen <hyrosen@mail.com> wrote
> I just want to make any classes derived from bachelor not be
> constructible.
In any reasonable programming shop, this is all you ought to need:
class bachelor {
// WARNING: DO NOT DERIVE any classes from bachelor
public:
...
};
If you're really working with children, just make your base non-template:
class no_children_for_bachelor {
no_children_for_bachelor() {}
no_children_for_bachelor(const &no_children_for_bachelor) {}
friend class bachelor;
};
class bachelor : virtual private no_children_for_bachelor { };
Slightly more typing -- but same net effect as the illegal template
version.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Hyman Rosen <hyrosen@mail.com>
Date: 09 Apr 03 05:00:20 GMT Raw View
Dan McLeran wrote:
> I just read an article today in the May edition of C/C++ Users Journal
> that uses your example to illustrate why you cannot do that.
> Consider:
> Foo<int> f;
> Obviously, int cannot be a friend.
No, this is not a good reason. Just because a template cannot be
instantiated for some particular values of the parameters, that
does not make the template ill-formed.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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. --- ]
Author: Hyman Rosen <hyrosen@mail.com>
Date: 09 Apr 03 05:00:28 GMT Raw View
Ron wrote:
> In the sense of "would it work?", nothing's wrong with it. However,
> it's not a Good Thing (strong coupling and all), and there are other,
> better ways to do what you want.
Strong coupling is irrelevant, because we're talking about
permitted expression within the language, not quality of
design. As for better ways, how do you do the "don't derive
from me" pattern? We want to say
template <typename T> class no_children {
no_children() { }
friend class T;
};
class bachelor : virtual no_children<bachelor> { };
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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. --- ]
Author: ksvap@yahoo.com (Stas Kondratiev)
Date: 9 Apr 2003 15:58:54 -0400 Raw View
I don't know if it's a BUG or a FEATURE in MS VC++ 6/7 ('cos I couldnt
find any info in MSDN), but this compilers allow the following syntax:
template <class T>
class A
{
friend T;
void f() {}
};
class B
{
public:
void f()
{
A<B> a;
a.f(); // No error here.
}
};
Best regards,
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: "John H. Spicer" <jhs@edg.com>
Date: 4 Apr 2003 17:48:33 -0500 Raw View
HumptyDumpty wrote:
> Hi all, does anyone know WHY template parameters cannot be declared friend
> of a template class, i.e.
>
> template <class T>
> struct Foo {
> friend class T;
> };
>
> is invalid according to the Standard. I can't see what's wrong with such
> declaration.
>
The following is something I posted to the standard committee's reflector last
September on this subject.
John Spicer
Edison Design Group
-----------------------------------------------------------------------------------------------
Whether or not "friend class T" should be permitted was discussed
in San Jose in November of 1993, where it was agreed that this should
be permitted.
Then in Waterloo, in July of 1994 we reopened the issue to address
cases like this:
template <class T> void f(struct T t){}
template <class T> void f(union T t){}
template <class T> void f(enum T t){}
union U {};
struct S {};
class C {};
enum E {};
int main()
{
U u;
S s;
C c;
E e;
f(u);
f(s);
f(c);
f(e);
}
The issue being whether or not you can choose a function template based
on the kind of elaborated type specifier that is present (something actually
supported by the EDG front end back in those days). The committee decided
against this, and as a result, a rule was added prohibiting a template
parameter from being used in an elaborated type specifier in a function
template declaration.
At the infamous Santa Cruz meeting in March of 1996 the issue was raised
again. The text below is from version 15 of my template issues paper
and covers the discussion in Santa Cruz.
So, it would be possible to simply permit "friend class T", but we'd have
to make sure that we address related issues like the ones raised in
Santa Cruz.
-------------------------------------------------------------------------------
From my template issues paper (version 15)
3.28 Elaborated type specifiers in function template declarations revisited.
In Waterloo, we decided that an elaborated type specifier containing a
template parameter name could not be used in a function template declaration.
Now that we have the partial ordering rules for function templates,
this issue should be checked to see if it is still what we want.
With the partial ordering rules, we can now select one template over another
based on one being ``more specialized'' than another. It seems that these
rules could be applied to elaborated type specifiers as well.
If this is permitted in the partial ordering of function templates, it should
also be permitted in the partial ordering used for class template partial
specializations.
template <class T> class List {};
template <class T> void f(List<struct T> l){} // #1
template <class T> void f(List<union T> l){} // #2
template <class T> void f(List<enum T> l){} // #3
template <class T> void f(List<T> l){} // #3
union U {};
struct S {};
class C {};
enum E {};int main()
{
List<U> u;
List<S> s;
List<C> c;
List<E> e;
List<int> i;
f(u); // calls #2
f(s); // calls #1
f(c); // calls #1
f(e); // calls #3
f(i); // calls #4
}
Answer:
Core-3 decided that the current rule banning use of template parameters
in elaborated type specifiers only in function template declarations
was not sufficient (because of things like partial specializations of
classes), and that a simple prohibition against the use of template
parameters in elaborated type specifiers was more desirable than
a more complicated rule.
Consequently, template parameters cannot be used in elaborated type specifiers.
-------------------------------------------------------------------------------
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: "Siemel Naran" <SiemelNaran@KILL.att.net>
Date: 4 Apr 2003 17:49:32 -0500 Raw View
"HumptyDumpty" <oliver.schoenborn@utoronto.ca> wrote in message
> Hi all, does anyone know WHY template parameters cannot be declared friend
> of a template class, i.e.
>
> template <class T>
> struct Foo {
> friend class T;
> };
>
> is invalid according to the Standard. I can't see what's wrong with such
> declaration.
I don't know why it is illegal.
However, would something like this solve your problem --
template <class Iter, class Calc, class Private>
class calculate_iterator : private Calc {
public:
calculate_iterator& operator++() { ++d_iter; return *this; }
value_type operator*() const { return Calc::operator(*d_iter); }
calculate_iterator(Iter iter, Private) : d_iter(iter) { }
Iter underlying(Private) const { return d_iter; }
private:
Iter d_iter;
};
The function underlying(...) returns the underlying representation. What
about the unused parameter of type Private? It isn't used, but we still
have to create it, which means that we need access to Private's constructor.
For example,
class Useful {
private:
class Private { };
typedef std::vector<Thing> container_type;
public:
typedef calculate_iterator<container_type::const_iterator, Id, Private>
const_iterator;
const_iterator begin() const;
};
By calling Useful::begin() we get the calculate_iterator. But we can't get
the underlying iterator because we don't have access to create Private's
constructor and therefore can't create a Private object. But member
functions of Useful can create a Private, and so can access the underlying
implementation.
--
+++++++++++
Siemel Naran
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Thomas Hansen <thomas.hansenNOSPAMORILLSUEYOURXXX@adramatch.com>
Date: 4 Apr 2003 17:50:13 -0500 Raw View
On 02 Apr 03 06:24:16 GMT, there came a drop of sanity from
"HumptyDumpty" <oliver.schoenborn@utoronto.ca> containing:
>Hi all, does anyone know WHY template parameters cannot be declared friend
>of a template class, i.e.
>
>template <class T>
>struct Foo {
> friend class T;
>};
>
>is invalid according to the Standard. I can't see what's wrong with such
>declaration.
>
>Thanks,
>Oliver
Well I have a friend somewhere around, I don't know who he is but I
know hes out there somewhere...
;)
--
"FOOT-AND-MOUTH BELIEVED TO BE FIRST VIRUS
UNABLE TO SPREAD THROUGH MICROSOFT OUTLOOK"
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Hyman Rosen <hyrosen@mail.com>
Date: 07 Apr 03 00:33:59 GMT Raw View
HumptyDumpty wrote:
> Hi all, does anyone know WHY template parameters cannot
> be declared friend of a template class, i.e.
> template <class T> struct Foo { friend class T; };
> is invalid according to the Standard. I can't see what's
> wrong with such declaration.
It's an accident. 11.4/2 says
An elaborated-type-specifier shall be used in a
friend declaration for a class.
ELaborated type specifiers are described in 3.4.4,
and the definition is such that 'class T' would
refer to a class named 'T', not to the template
parameter. I hope this will get fixed up for the
revision.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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. --- ]
Author: dan.r.mcleran@seagate.com (Dan McLeran)
Date: 7 Apr 2003 20:00:57 -0400 Raw View
> Hi all, does anyone know WHY template parameters cannot be declared friend
> of a template class, i.e.
>
> template <class T>
> struct Foo {
> friend class T;
> };
>
> is invalid according to the Standard. I can't see what's wrong with such
> declaration.
I just read an article today in the May edition of C/C++ Users Journal
that uses your example to illustrate why you cannot do that.
Consider:
Foo<int> f;
Obviously, int cannot be a friend.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: rcrane@ictv.com (Ron)
Date: 7 Apr 2003 20:01:26 -0400 Raw View
> Hi all, does anyone know WHY template parameters cannot be declared friend
> of a template class, i.e.
>
> template <class T>
> struct Foo {
> friend class T;
> };
>
> is invalid according to the Standard. I can't see what's wrong with such
> declaration.
In the sense of "would it work?", nothing's wrong with it. However,
it's not a Good Thing (strong coupling and all), and there are other,
better ways (such as
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=d522680b.0204232313.5ad00113%40posting.google.com&rnum=3
) to do what you want.
-- Ron
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: "HumptyDumpty" <oliver.schoenborn@utoronto.ca>
Date: 02 Apr 03 06:24:16 GMT Raw View
Hi all, does anyone know WHY template parameters cannot be declared friend
of a template class, i.e.
template <class T>
struct Foo {
friend class T;
};
is invalid according to the Standard. I can't see what's wrong with such
declaration.
Thanks,
Oliver
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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. --- ]