Thread View: comp.std.c++
10 messages
10 total messages
Started by Eugene Radchenko
Mon, 29 Jan 1996 10:38
Observations on templates
Author: Eugene Radchenko
Date: Mon, 29 Jan 1996 10:38
Date: Mon, 29 Jan 1996 10:38
72 lines
4004 bytes
4004 bytes
Hi people!
I want to share some thoughts on the template section of the (April) draft
standard (BTW, is ASCII version of September one is available somewhere?
Easily editable/reformattable version (e.g. WinWord or RTF) would be even
better).
Generally, I like it very much. In fact while reading it I had that
'Here-is-what-I-longed-for' feeling which I last had (programming-wise)
when reading Stroustroup's book 5 years ago. Some things I do not
understand, however, and would like the committee members to provide
'rationale on demand' and explain what is the point of some finer points.
1) Clause [temp.res] verse 1 requires that all types dependent on the
template parameter must be qualified by 'typename' keyword - supposedly to
allow checking the template syntax. But it does not help anything as _each_
instance will have to be checked anyway:
e.g.
struct X {
static int A;
class B { };
}
template <class T> class Y {
typename T::A *ap; // error in Y<X> - T::A is not a type
T::B *bp; // error - no 'typename'
}
2) Clause [temp.dep] verse 5 states that base class scope names hide the
template parameter:
struct A { struct B{}; };
template <class B, class C> struct X : A {
B b; //A's B
};
However, as base class is the enclosing scope, I would intuitively expect
anything related to the derived class (its template parameter, for
instance) to hide its names. Moreover, we can use A::B to access A's B -
while template parameter is now inaccessible. Also, base class definition
may be inaccessible. Of course, you can change the temp. param. name - but
anyway it is not nice.
3) Clause [temp.arg.explicit] verses 2-3 requires that for explicit arg in
member template to be present it must be qualified by 'template' keyword,
e.g.
X *p; p->template alloc<200>();
But to use operator -> we need X class definition anyway - so we know that
alloc() is a template. Thus this keyword is redundant and likely to be
forgotten (if I am not mistaken, it is in fact missing from some examples
in lib.locale section).
4) Clause [temp.deduct] verse 4. Why the conversions other than Derived* ->
Base* are not allowed in template deduction (at least default conversions
like char->int; user conversions would be even better)?
Best regards Genie
PS. Am I the only one who does not like the current drift in the C++ syntax
from symbolic (C-like)
int a[10];
to verbose (Pascal-like)
var
a: array[0..9] of integer;
way of expressing things? Why don't use, for instance, cast_d instead od
dynamic_cast (ugh). Yeah, I know we are not using 10-cps terminals Richie
(sp?) did, but anyway... (and it consumes compiler memory space :-)
--
--------------------------------------------------------------------
Eugene V. Radchenko Research associate, Computer Chemistry
E-mail: eugene@qsar.chem.msu.su Fax: +7-(095)939-0290
Ordinary mail: Chair of Organic Chemistry, Department of Chemistry,
Moscow State University, 119899 Moscow, Russia
***************** Disappearances are deceptive *******************
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Observations on templates
Author: David Vandevoorde
Date: Mon, 29 Jan 1996 19:15
Date: Mon, 29 Jan 1996 19:15
76 lines
3966 bytes
3966 bytes
>>>>> "E" == "Eugene Radchenko" <eugene@qsar.chem.msu.su> writes:
[...]
E> 1) Clause [temp.res] verse 1 requires that all types dependent on the
E> template parameter must be qualified by 'typename' keyword - supposedly to
E> allow checking the template syntax. But it does not help anything as _each_
E> instance will have to be checked anyway:
[...]
I don't think that `typename' was introduced with the intention of avoiding
instantiation checks. I expect at least one of the goals was to permit the
development of more refined tools (e.g., for the analysis of generic as
opposed to instantiated code).
E> 2) Clause [temp.dep] verse 5 states that base class scope names hide the
E> template parameter:
[...]
Although I didn't check the issue, I would tend to agree with you here.
In particular, consider:
template<typename B>
struct D: public B {
// Cannot guarantee that a member of B won't hide the
// classname itself.
}
Again, I didn't check this (i.e., what I say above may be unfounded).
E> 3) Clause [temp.arg.explicit] verses 2-3 requires that for explicit arg in
E> member template to be present it must be qualified by 'template' keyword,
E> e.g.
E> X *p; p->template alloc<200>();
E> But to use operator -> we need X class definition anyway - so we know that
E> alloc() is a template. Thus this keyword is redundant and likely to be
E> forgotten (if I am not mistaken, it is in fact missing from some examples
E> in lib.locale section).
Same as 1).
E> 4) Clause [temp.deduct] verse 4. Why the conversions other than Derived* ->
E> Base* are not allowed in template deduction (at least default conversions
E> like char->int; user conversions would be even better)?
I suppose this is a matter of avoiding complexity. Remember that the more
possibilities the compiler must consider, the more time it will take to
compile this code (and in this case we're talking about superlinear
growth). From a maintainability point of view, implicit conversion can
also be a hassle.
[...]
E> PS. Am I the only one who does not like the current drift in the C++ syntax
E> from symbolic (C-like)
E> int a[10];
E> to verbose (Pascal-like)
E> var
E> a: array[0..9] of integer;
E> way of expressing things? Why don't use, for instance, cast_d instead od
E> dynamic_cast (ugh). Yeah, I know we are not using 10-cps terminals Richie
E> (sp?) did, but anyway... (and it consumes compiler memory space :-)
[...]
I think that what you're observing is the tendency to require (or encourage)
us to ``say what we mean''. The new casting syntax, the ban on implicit int,
the explicit keyword, the uses of `typename' and `template' syntax that you
mention and even the bool type are all ways to make more explicit in the
source code what is going on. Considering the things that already happen
automatically in C++ (virtual dispatch, template instantiation, destruction,
user-defined conversions, ...), I am rather happy that those things that do
not require transparency are made explicit.
Daveed
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Observations on templates
Author: Jason Merrill
Date: Tue, 30 Jan 1996 04:52
Date: Tue, 30 Jan 1996 04:52
41 lines
2490 bytes
2490 bytes
>>>>> Eugene Radchenko <eugene@qsar.chem.msu.su> writes: > 1) Clause [temp.res] verse 1 requires that all types dependent on the > template parameter must be qualified by 'typename' keyword - supposedly to > allow checking the template syntax. But it does not help anything as _each_ > instance will have to be checked anyway: Requiring 'typename' allows syntactic analysis and some name binding to be done at the point of definition of the template. Older implementations do all name binding at the point of instantiation, which was thought to be confusing. Each instance will indeed have to be checked, but only for semantic correctness, not syntactic. > 2) Clause [temp.dep] verse 5 states that base class scope names hide the > template parameter: This is for orthogonality. Think of the template header as creating a special scope around the class; name lookups in class scope look in the current class, then in base classes, then in the surrounding scope. Note that template parameters used as base types are not affected by this rule, since name binding is done on the template definition, before the base is known. > 3) Clause [temp.arg.explicit] verses 2-3 requires that for explicit arg in > member template to be present it must be qualified by 'template' keyword, > e.g. > X *p; p->template alloc<200>(); > But to use operator -> we need X class definition anyway - so we know that > alloc() is a template. It is needed in some situations where we do not have the X class definition -- in template definitions, like with typename. Jason --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Observations on templates
Author: Jason Merrill
Date: Thu, 01 Feb 1996 00:07
Date: Thu, 01 Feb 1996 00:07
25 lines
1882 bytes
1882 bytes
>>>>> Jason Merrill <jason@cygnus.com> writes: >>>>> Eugene Radchenko <eugene@qsar.chem.msu.su> writes: >> 3) Clause [temp.arg.explicit] verses 2-3 requires that for explicit arg in >> member template to be present it must be qualified by 'template' keyword, >> e.g. >> X *p; p->template alloc<200>(); >> But to use operator -> we need X class definition anyway - so we know that >> alloc() is a template. > It is needed in some situations where we do not have the X class definition > -- in template definitions, like with typename. But then, the rule in the WP applies regardless of whether we know about X. I conclude that the idea was to allow the parser to do its work without peeking into classes to find names used after . or ->; another rule along the same lines requires that a scope used after . or -> have the same meaning in the ambient scope and the scope of the object specified. Jason [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Observations on templates
Author: John Max Skaller
Date: Mon, 05 Feb 1996 17:25
Date: Mon, 05 Feb 1996 17:25
18 lines
1507 bytes
1507 bytes
Eugene Radchenko wrote:
> Why don't use, for instance, cast_d instead od
> dynamic_cast (ugh).
This is quite deliberate. Bjarne dislikes casts. So do I.
He didn't invent new style casts (and RTTI) for your convenience,
he invented them to make sure no one else did. Long names were deliberately
chosen to discourage use of casts.
--
John Max Skaller voice: 61-2-566-2189
81 Glebe Point Rd fax: 61-2-660-0850
GLEBE NSW 2037 web: http://www.maxtal.com.au/~skaller/
AUSTRALIA email: skaller@maxtal.com.au
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Re: Observations on templates
Author: Ken Walter
Date: Wed, 07 Feb 1996 15:57
Date: Wed, 07 Feb 1996 15:57
33 lines
1661 bytes
1661 bytes
In message <3114137D.CFC@suphys.physics.su.oz.au> - John Max Skaller <maxtal@su
phys.physics.su.oz.au> writes:
:>
:>Eugene Radchenko wrote:
:>> Why don't use, for instance, cast_d instead od
:>> dynamic_cast (ugh).
:>
:> This is quite deliberate. Bjarne dislikes casts. So do I.
:>He didn't invent new style casts (and RTTI) for your convenience,
:>he invented them to make sure no one else did. Long names were deliberately
:>chosen to discourage use of casts.
:>
But dynamic casts are almost required to do anything.
I always thought the following was interesting:
template <class T, class S> T cast_d( S s) { return dynamic_cast<T>s; }
and the expression:
cast_d<T>(s)
Casts could almost be implemented without being part of the language.
Ken Walter
* All the above is hearsay and the opinion of nobody in particular
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
summarized in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
]
Re: Observations on templates
Author: Fergus Henderson
Date: Mon, 12 Feb 1996 05:03
Date: Mon, 12 Feb 1996 05:03
26 lines
1718 bytes
1718 bytes
solution@gate.net (Ken Walter) writes:
>I always thought the following was interesting:
>
>template <class T, class S> T cast_d( S s) { return dynamic_cast<T>s; }
That won't quite do what you want, because you are using
pass-by-value. That will result in copying, giving `cast_d' quite
different semantics to `dynamic_cast'. You should use
pass-by-reference instead. You then need to overload the function to
allow all possible sorts of references:
template <class T, class S> T cast_d(S &s) { return dynamic_cast<T>s; }
template <class T, class S> T cast_d(const S &s) { return dynamic_cast<T>s; }
template <class T, class S> T cast_d(volatile S &s)
{ return dynamic_cast<T>s; }
template <class T, class S> T cast_d(const volatile S &s)
{ return dynamic_cast<T>s; }
--
Fergus Henderson WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au PGP: finger fjh@128.250.37.3
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. Moderation policy:
http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Re: Observations on templates
Author: David Vandevoorde
Date: Mon, 12 Feb 1996 15:07
Date: Mon, 12 Feb 1996 15:07
19 lines
1476 bytes
1476 bytes
>>>>> "FH" == Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:
[...]
FH> template <class T, class S> T cast_d(S &s)
{ return dynamic_cast<T>s; }
FH> template <class T, class S> T cast_d(const S &s)
{ return dynamic_cast<T>s; }
FH> template <class T, class S> T cast_d(volatile S &s)
FH> { return dynamic_cast<T>s; }
FH> template <class T, class S> T cast_d(const volatile S &s)
FH> { return dynamic_cast<T>s; }
Isn't the last one sufficient? (and aren't parentheses required in
`dynamic_cast<T>(s)'?).
Daveed
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. Moderation policy:
http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Re: Observations on templates
Author: Pulkkinen Esa
Date: Mon, 12 Feb 1996 18:16
Date: Mon, 12 Feb 1996 18:16
20 lines
1851 bytes
1851 bytes
In article <4fa6d0$115g@news.gate.net>, Ken Walter <solution@gate.net> wrote:
>template <class T, class S> T cast_d( S s) { return dynamic_cast<T>s; }
>Casts could almost be implemented without being part of the language.
>
They can. But it's too much work for the programmer to do it. I've used
a simulation of a dynamic_cast when I didn't have a compiler that supports
them. The problem with such a simulation is that you have to provide
most of the information dynamic_cast uses by yourself (for the second time),
even though you have already provided the compiler with the same
information in the class declaration. Or you can use macro hackery
to do that for you, but that's ugly.
--
Esa Pulkkinen | C++ programmers do it virtually
E-Mail: esap@cs.tut.fi | everywhere with a class, resulting
WWW : http://www.cs.tut.fi/~esap/ | in multiple inheritance.
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Re: Observations on templates
Author: Fergus Henderson
Date: Mon, 12 Feb 1996 18:22
Date: Mon, 12 Feb 1996 18:22
46 lines
2351 bytes
2351 bytes
vandevod@cs.rpi.edu (David Vandevoorde) writes:
>>>>>> "FH" == Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:
>[...]
>FH> template <class T, class S> T cast_d(S &s)
> { return dynamic_cast<T>s; }
>FH> template <class T, class S> T cast_d(const S &s)
> { return dynamic_cast<T>s; }
>FH> template <class T, class S> T cast_d(volatile S &s)
>FH> { return dynamic_cast<T>s; }
>FH> template <class T, class S> T cast_d(const volatile S &s)
>FH> { return dynamic_cast<T>s; }
>
>Isn't the last one sufficient?
No, because 5.2.6[expr.cast.dynamic]/1 states that "dynamic_cast shall
not cast away constness". If you only defined the last one, then code
such as
class Foo : public Bar { /* ... */ };
void f(Bar& x) {
cast_d<Foo&>(x);
}
would be ill-formed, because it would instantiate
cast_d<Foo&, Bar> Foo& cast_d(const volatile Bar &s)
{ return dynaic_cast<Foo&>(s); }
and this dynamic_cast would be casting away constness.
Incidentally, 5.2.6 would seem to imply that dynamic_cast *is* allowed
to cast away volatileness, but I think that is a mistake in the current
draft.
>(and aren't parentheses required in `dynamic_cast<T>(s)'?).
Yes, they are -- thanks for correcting that error.
--
Fergus Henderson WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au PGP: finger fjh@128.250.37.3
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads