🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

10 total messages Started by Eugene Radchenko Mon, 29 Jan 1996 10:38
Observations on templates
#3130
Author: Eugene Radchenko
Date: Mon, 29 Jan 1996 10:38
72 lines
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
#3137
Author: David Vandevoorde
Date: Mon, 29 Jan 1996 19:15
76 lines
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
#3141
Author: Jason Merrill
Date: Tue, 30 Jan 1996 04:52
41 lines
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
#3171
Author: Jason Merrill
Date: Thu, 01 Feb 1996 00:07
25 lines
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
#3235
Author: John Max Skaller
Date: Mon, 05 Feb 1996 17:25
18 lines
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
#3297
Author: Ken Walter
Date: Wed, 07 Feb 1996 15:57
33 lines
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
#3319
Author: Fergus Henderson
Date: Mon, 12 Feb 1996 05:03
26 lines
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
#3343
Author: David Vandevoorde
Date: Mon, 12 Feb 1996 15:07
19 lines
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
#3317
Author: Pulkkinen Esa
Date: Mon, 12 Feb 1996 18:16
20 lines
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
#3321
Author: Fergus Henderson
Date: Mon, 12 Feb 1996 18:22
46 lines
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