Topic: Template constraints
Author: dag@control.lth.se (Dag Bruck)
Date: 17 Aug 1993 18:46:03 GMT Raw View
In <comp.std.c++> jjb@watson.ibm.com (John Barton) writes:
>In article <244rc6$g7i@nic.lth.se>, dag@control.lth.se (Dag Bruck) writes:
>|>
>|> So the idea is that you specify the minimum interface in a separate
>|> class declaration, and then only list the class name(s) in the
>|> template argument list.
>
> Any compiler or C++ syntax analyzer can produce the information
>listed in T_templ above. Having the programmer type it in is silly.
No. First, the syntax analyser can only synthesize such information
if it has access to the complete source code for the template
class/function. That may not be the case when the template
implementation resides in a separate file, and you may also want to
syntax check your own code with access to .h files only.
Second, a user-defined T_templ can define restrictions that are not
inherrent in the source code of the template definition. You may
impose requirements based on planned template implementations etc.
that not actually needed with the current implementation. For
example, you may require that array elements must have a default
constructor, just in case you want to implement element initialization
in some future release.
-- Dag
Author: dag@control.lth.se (Dag Bruck)
Date: 17 Aug 1993 18:52:08 GMT Raw View
In <comp.std.c++> ark@alice.UUCP () writes:
>
>One way of solving this problem, which I think I and several other people
>have suggested independently, is something like this:
[Summary of proposal.]
class T;
means that T is a some type.
I think this is a bad idea, because T may not necessarily be a class,
struct or union:
typedef int T;
....
class T; // yuck
I think this is not quite intuitive and blurs the distinction between
built-in types and classes. Do we want this distinction? Maybe not,
but I belive that people would for example expect to be able to derive
new classes from something called "class." I still prefer
typedef T;
inspite of the problems incurred by "implict int."
-- Dag
Author: chased@rbbb.Eng.Sun.COM (David Chase)
Date: 20 Aug 1993 19:29:27 GMT Raw View
>>In article <rfgCBAw1F.7Hx@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>>>Regarding the problem of syntax checking of templates...
>>
>>>I have already (informally) suggested what I feel is a convenient and
>>>intutively obvious notation for indicating which members of template
>>>formal type arguments are themselves types. It neither introduces
>>>new keywords nor involves any conflicts with any existing syntax.
>>>Here is a brief example:
>>> int a;
>>>
>>> template <class T { class M; }> void template_function (T arg)
>>> {
>>> T::M (a); // declaration; not a call
>>> }
>>>Note that in this example, it would be erroneous for this template to be
>>>instantiated with some actual type T' which failed to have a type member
>>>with the name `M'.
>>>Having this "instantiation constraint" appear within the list of template
>>>formals might also prove valuable in cases where a given translation unit
>>>contains only a declaration of the template, but not a definition, as in:
>>> template <class T { class M; }> void template_function (T);
>In article <m663quINNhtq@exodus.Eng.Sun.COM> chased@rbbb.Eng.Sun.COM (David Chase) writes:
>>Is there any particular reason why you wouldn't extend this to include
>>more than just type constraints? ...
[ followed by proposal with a sort of type skeleton filled in,
with intention that that be part of the interface to the
template. ]
In article <rfgCBtKFC.KBG@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>Yes. I would not do that because I was only trying to solve one particular
>(small) problem. If anyone else thinks that X3J16 ought to consider some
>more ambitious scheme which would solve some larger set of problems, and
>if that person (or persons) want to draft an extensions proposal and submit
>it to X3J16... well... be my guest.
Well, I think the lack-of-interface(*)-to-template and the apparent
blurring of link and compile times are bigger problems than this weird
syntactic nit, though that is a problem as well. I think it's fairly
important to (for instance) be able to ship a new version of a
template implementation without forcing recompiles. The current
template definition doesn't seem to allow this without some small
breakage of the "as if textually expanded" rule (that is a good rule,
too - short and easy to understand. However, textual expansion is not
always the best implementation technique, though it is adequate in a
compiler prototype.)
(*) If the interface is derived from the implementation (as one poster
proposed) and doesn't actually constrain future implementations, then
I'm not sure that it's really an interface.
This seemed like such an obvious problem to me that I just assumed
that someone else would have already set out to fix it. If you think
that an extensions proposal would be worthwhile and given serious
consideration, then I suppose I can try it (at least one person on the
committee knows that I am a serious C++ skeptic, and I don't know if
that would hurt or harm the chances of the proposal).
David Chase
SunPro (speaking for myself)
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 15 Aug 1993 21:09:05 GMT Raw View
In article <744662863@amazon.cs.duke.edu> dsb@duke.cs.duke.edu (Scott Bigham) writes:
>In article <rfgCBAw1F.7Hx@netcom.com>, Ronald F. Guilmette
>(rfg@netcom.com) suggests the following syntax extension to implement
>compile-time-enforceable template constraints:
HOLD ON A SECOND! I just want to clarify that it was *YOU* and *YOU ALONE*
who decided to use the term "template constraints" with regard to the
rather simple suggestion that I posted (regarding a method for declaring
which members of template formal types are themselves types).
I do not wish to call what I suggested "template constraints", nor do I think
that would be at all appropriate. That term (obviously) connotes something
far beyond (and essentially unrelated to) the issue I was attempting to
address (i.e. making it possible to *JUST* do complete syntax analysis
on template definitions... even in the total absence of any instantiations).
>> int a;
>>
>> template <class T { class M; }> void template_function (T arg)
>> {
>> T::M (a); // declaration; not a call
>> }
>
>An interesting proposal, and one which raises a number of questions:
>
>- Would the following (IMHO intuitive) constraints also be allowed?
>
> template <class T { int required_data_member; }> void F(T);
> template <class T { void required_member_fn(void); }>
> void G(T);
> template <class T { void parametrized_constraint(T); }>
> void H(T);
> template <class T { T another_parametrized_constraint; }>
> void I(T);
> template <class T { T operator + (const T &); }> void J(T);
> template <class T { class Multiple; class Constraints; }>
> void K(T);
> template <class T: public Constrain_By_Base_Class> void L(T);
> // and would indirect derived classes satisfy this constraint?
Let me just say that you seem to have let your imagination and creativity
get the better of you, and while your various ideas for some sort of a new
"template constraints" feature(s) may be interesting in their own right,
they bear little or no relationship to the very modest idea I had put
forward earlier to solve one very small (and very well defined) problem
relating ONLY to syntax analysis.
Indeed, I am somewhat disheartened that the follow-ups on my simple idea
for solving this one small (syntax) problem have blossomed out into
discussions of vastly more complicated "template constraint" schemes, the
soundness and/or need for which have yet to be adequately demonstrated.
I can only hope that casual observers of this thread will not mistakenly
equate simple resolutions of the syntax problem for template definitions
to these far more grandious and ambitious "template constraint" schemes.
(For some additional information relating to YOUR ambitious template
constraint scheme, I can refer you to Stroustrup's original paper on
templates, appearing in the Proceedings of the first USENIX C++ Conference,
October 1988. In that paper, Stroustrup explains, on the first half of
page 6, why he rejected the idea of allowing the specification of detailed
constraints on template formal type arguments. I will not say here whether
I agree or disagree with Stroustrup's analysis, but I will say that those
who would wish to revisit this design decision would be well advised to
at least familiarize themselves with Stroustrup's analysis before under-
taking to question the conclusions which he reached.)
In any case, I think it is important (especially for the X3J16 members who
follow this newsgroup) to realize that it is possible to solve the syntax
analysis problem for template definitions WITHOUT opening the door to some
vastly more complicated template constraints scheme. The simple template
syntax problem can be (and should be) solved simply. Other unrelated
issues can be (and should be) considered separately.
--
-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 15 Aug 1993 21:16:24 GMT Raw View
In article <m663quINNhtq@exodus.Eng.Sun.COM> chased@rbbb.Eng.Sun.COM (David Chase) writes:
>In article <rfgCBAw1F.7Hx@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>>Regarding the problem of syntax checking of templates...
>
>>I have already (informally) suggested what I feel is a convenient and
>>intutively obvious notation for indicating which members of template
>>formal type arguments are themselves types. It neither introduces
>>new keywords nor involves any conflicts with any existing syntax.
>
>>Here is a brief example:
>
>> int a;
>>
>> template <class T { class M; }> void template_function (T arg)
>> {
>> T::M (a); // declaration; not a call
>> }
>
>>Note that in this example, it would be erroneous for this template to be
>>instantiated with some actual type T' which failed to have a type member
>>with the name `M'.
>
>>Having this "instantiation constraint" appear within the list of template
>>formals might also prove valuable in cases where a given translation unit
>>contains only a declaration of the template, but not a definition, as in:
>
>> template <class T { class M; }> void template_function (T);
>
>Is there any particular reason why you wouldn't extend this to include
>more than just type constraints? ...
Yes. I would not do that because I was only trying to solve one particular
(small) problem. If anyone else thinks that X3J16 ought to consider some
more ambitious scheme which would solve some larger set of problems, and
if that person (or persons) want to draft an extensions proposal and submit
it to X3J16... well... be my guest.
--
-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
Author: mat@mole-end.matawan.nj.us
Date: Mon, 16 Aug 1993 00:41:33 GMT Raw View
In article <rfgCBAw1F.7Hx@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
> Regarding the problem of syntax checking of templates...
...
> (It is a fairly well known fact that it is often hard, if not impossible to
> produce link-time diagnostics which point the user back to the original
> source file and original source line which is really causing the problem.
> Therefore, if given the choice, I would always opt for a language design
> which makes it possible to generate a maximal number of the required
> diagnostics at compile-time rather than putting everything off until link-
> time.)
Ron, I hope you'll forgive me if I tread this ground again; I know we've
done it elsewhere.
The `compile-then-link' model assumes that all semantic analysis (and code
generation) can be performed before any name resolution (or relocation).
Templates break this assumption, since semantic analysis must be deferred
until the template is specialized, and the template can't be specialized
until the entire program is present (because specialization depends on what
has been written `manually').
Thus the notions of `compile time' and `link time' get rather badly blurred.
--
(This man's opinions are his own.)
From mole-end Mark Terribile
mat@mole-end.matawan.nj.us, Somewhere in Matawan, NJ
Author: dsb@duke.cs.duke.edu (Scott Bigham)
Date: 16 Aug 93 14:26:16 GMT Raw View
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Mon, 16 Aug 1993 17:08:22 GMT Raw View
In article <1993Aug16.004133.23916@mole-end.matawan.nj.us> mat@mole-end.matawan.nj.us writes:
>In article <rfgCBAw1F.7Hx@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
>
>> Regarding the problem of syntax checking of templates...
> ...
>> (It is a fairly well known fact that it is often hard, if not impossible to
>> produce link-time diagnostics which point the user back to the original
>> source file and original source line which is really causing the problem.
>> Therefore, if given the choice, I would always opt for a language design
>> which makes it possible to generate a maximal number of the required
>> diagnostics at compile-time rather than putting everything off until link-
>> time.)
>
>Ron, I hope you'll forgive me if I tread this ground again; I know we've
>done it elsewhere.
>
>The `compile-then-link' model assumes that all semantic analysis (and code
>generation) can be performed before any name resolution (or relocation).
>Templates break this assumption, since semantic analysis must be deferred
>until the template is specialized, and the template can't be specialized
>until the entire program is present (because specialization depends on what
>has been written `manually').
>
>Thus the notions of `compile time' and `link time' get rather badly blurred.
While I would agree that templates do indeed have such a "blurring" effect,
they most certainly DO NOT (and cannot) eliminate the important distinction
between "compile-time" and "link-time" as far as the C++ standard is concerned.
There will ALWAYS be errors which MUST be diagnosed at "compile-time", and,
similarly, there will always be certain kinds of errors which MUST be
diagnosed at "link-time".
To the extent that diagnostics for template-related (erroneous) usage is
NOT explicitly mandated to occur at one or the other of these two times,
the specification (in the C++ standard) of the templates feature is incom-
plete.
--
-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Mon, 16 Aug 1993 17:19:07 GMT Raw View
In article <745511175@amazon.cs.duke.edu> dsb@duke.cs.duke.edu (Scott Bigham) writes:
>>
>>HOLD ON A SECOND! I just want to clarify that it was *YOU* and *YOU ALONE*
>>who decided to use the term "template constraints" [...]
>
>Er um, check the title of the thread. It was that way when I got here.
OK. Sorry. I stand corrected.
>And you did say, did you not, that given:
>
>>>> template <class T { class M; }> void template_function (T arg)
>
>that it would be a _compile-time_error_ to attempt to instantiate
>template_function() with a class that did not contain a type name M?
>Sounds like a template constraint to me.
If you like... but I just don't want to use that term for my tiny suggestion.
It sounds far too grandious.
>>Indeed, I am somewhat disheartened that the follow-ups on my simple idea
>>for solving this one small (syntax) problem have blossomed out into
>>discussions of vastly more complicated "template constraint" schemes [...]
>
>It surprises me that this surprises you. The syntax you suggest:
>
>>>> template <class T { class M; }> void template_function (T arg)
> ^^^^^^^^^^^^
>
>looks very much like a partial class definition for T; it should come
>as no surprise, then, that people would try to put other elements of a
>class definition into it.
True. Very true. I am not "surprized", but I am still a bit disheartened
by this general trend (among C++ buffs) to complexify everything to the
Nth degree.
>Besides, the most straightforward method of fixing the syntax problem
>would seem to be to disallow the extra parentheses in the declarator,
>since that's what's really causing the ambiguity in the first place:
You are (in some sense) right about that, but it would be equally true to
say that the whole template feature of C++ gives rise to the parse ambiguity
problem we have been discussing.
It would be possible (I think) to solve the problem in the manner you have
suggested, but that approach has the unfortunate side-effect of breaking
compatability with ANSI C (unnecessarily, in my opinion). Rather than do
that, it would seem more advisable to solve this problem (which arises
only in the context of C++ templates) by tweeking the rules relating to
templates.
>>(For some additional information relating to YOUR ambitious template
>>constraint scheme [...]
>
>Not mine alone, considering the number of people who independently
>suggested it.
Good point. I stand corrected (again).
I recommend that ALL parties who have expressed an interest in some more
generalized "template constraint" scheme should take a look at page 6 of
Stroustrup's original paper on templates (where he directly addresses this
issue).
--
-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
Author: ark@alice.att.com (Andrew Koenig)
Date: 17 Aug 93 00:00:10 GMT Raw View
In article <rfgCBv43v.LJB@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
> In article <745511175@amazon.cs.duke.edu> dsb@duke.cs.duke.edu (Scott Bigham) writes:
> >It surprises me that this surprises you. The syntax you suggest:
> >>>> template <class T { class M; }> void template_function (T arg)
> >looks very much like a partial class definition for T; it should come
> >as no surprise, then, that people would try to put other elements of a
> >class definition into it.
> True. Very true. I am not "surprized", but I am still a bit disheartened
> by this general trend (among C++ buffs) to complexify everything to the
> Nth degree.
This trend does not seem to be limited to C++ buffs.
One way of solving this problem, which I think I and several other people
have suggested independently, is something like this:
template<class T> void template_function (T arg)
{
class T::M;
// ...
}
I think this has the advantage of requiring no really new syntax,
as well as generalizing nicely to things like
class T::M (x);
which is already defined as equivalent to
T::M x;
if T::M is known to be a type.
--
--Andrew Koenig
ark@research.att.com
Author: jjb@watson.ibm.com (John Barton)
Date: Fri, 13 Aug 1993 12:33:59 GMT Raw View
In article <244rc6$g7i@nic.lth.se>, dag@control.lth.se (Dag Bruck) writes:
|> In <comp.std.c++> chased@rbbb.Eng.Sun.COM (David Chase) writes:
|> >In article <....> rfg@netcom.com (Ronald F. Guilmette) writes:
|> >>Here is a brief example:
|> >> template <class T { class M; }> void template_function (T);
|> >
|> >Is there any particular reason why you wouldn't extend this to include
|> >more than just type constraints?
|> >
|> > template <class T { unsigned hash(T);
|> > T();
|> > ~T();
|> > int operator==()(T,T);
|> > } > class Htable { .....
|> > } ;
|>
|> I think this is absolutely hideous :-) I really don't want to read
|> template argument lists like that. However, I think you could do it
|> as a two-step process by first declaring a template-argument-template,
|> if you excuse the pun:
|>
|> class T_templ {
|> unsigned hash(T);
|> T();
|> ~T();
|> int operator==()(T,T);
|> };
|>
|> template <class T : T_templ > class Htable { .....
|> } ;
|>
|> So the idea is that you specify the minimum interface in a separate
|> class declaration, and then only list the class name(s) in the
|> template argument list. There are two main advantages:
|>
|> - the template argument lists is kept reasonably short
|>
|> - it is easy to see that a group of template classes or
|> template functions have the same constraints, because
|> the all refer to the same name. It is also easier to
|> tell if two type arguments have the same constraints.
|>
|> Anyone cares to comment?
|>
|>
|> -- Dag
Any compiler or C++ syntax analyzer can produce the information
listed in T_templ above. Having the programmer type it in is silly.
On the other hand, an analyzer cannot determine what "T::X * y;" means
by any analysis short of template instantiation or guessing. We need
a way to forward declare the types for template arguments. We have
exactly the same problem for nested types in general: we cannot
now forward declare a type nested inside of another type.
There is a sensible line we can draw for limiting the
pre-declaration info to a template parameter: limit it to types
relations essential for syntax analysis. Accomplish this and
then work on wider issues.
--
John.
John J. Barton jjb@watson.ibm.com (914)784-6645
H1-C13 IBM Watson Research Center P.O. Box 704 Hawthorne NY 10598
Author: hendrik@vedge.com (Hendrik Boom)
Date: Fri, 13 Aug 1993 18:16:46 GMT Raw View
dag@control.lth.se (Dag Bruck) writes:
: In <comp.std.c++> chased@rbbb.Eng.Sun.COM (David Chase) writes:
: >In article <....> rfg@netcom.com (Ronald F. Guilmette) writes:
: >>Here is a brief example:
: >> template <class T { class M; }> void template_function (T);
: >
: >Is there any particular reason why you wouldn't extend this to include
: >more than just type constraints?
: >
: > template <class T { unsigned hash(T);
: > T();
: > ~T();
: > int operator==()(T,T);
: > } > class Htable { .....
: > } ;
:
: I think this is absolutely hideous :-) I really don't want to read
: template argument lists like that. However, I think you could do it
: as a two-step process by first declaring a template-argument-template,
: if you excuse the pun:
:
: class T_templ {
: unsigned hash(T);
At this point, T is not declared.
There's cetainly no hint that it has anything to do with template parameters.
: T();
: ~T();
: int operator==()(T,T);
: };
:
: template <class T : T_templ > class Htable { .....
: } ;
:
: So the idea is that you specify the minimum interface in a separate
: class declaration, and then only list the class name(s) in the
: template argument list. There are two main advantages:
:
: - the template argument lists is kept reasonably short
:
: - it is easy to see that a group of template classes or
: template functions have the same constraints, because
: the all refer to the same name. It is also easier to
: tell if two type arguments have the same constraints.
:
: Anyone cares to comment?
:
:
: -- Dag
--
-------------------------------------------------------
Try one or more of the following addresses to reply.
at work: hendrik@vedge.com, iros1!vedge!hendrik
at home: uunet!ozrout!topoi!hendrik
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Thu, 5 Aug 1993 19:12:51 GMT Raw View
Regarding the problem of syntax checking of templates...
In article <1993Aug4.182811.21153@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>In article <rfgCB638z.2t3@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>>
>>Once the committee has come to a consensus that the problem is worth fixing,
>>then I may provide a suggestion for one way of fixing the problem (just as
>>you have) but mine would only be one among many possible solutions.
>
> Provide away: the extensions group believes the problem
>is worth fixing.
>
>>
>>A technical analysis of the pros and cons of all of the suggested solutions
>>may be useful (at some future point in time), but it would be utterly
>>pointless until such time as the committee decides that the problem ought
>>to be fixed. That however is a separate decision, and one which is not
>>so much technical as it is esthetic.
>
> Irrelevant since the extension group has already made
>the decision that the problem ought to be fixed. That doesn't mean
>it will be: both the solutions I remember being considered
>had problems.
>
> Would you introduce a new keyword to solve the problem?
>If not, how would you use the existing keywords?
I have already (informally) suggested what I feel is a convenient and
intutively obvious notation for indicating which members of template
formal type arguments are themselves types. It neither introduces
new keywords nor involves any conflicts with any existing syntax.
Here is a brief example:
int a;
template <class T { class M; }> void template_function (T arg)
{
T::M (a); // declaration; not a call
}
Note that in this example, it would be erroneous for this template to be
instantiated with some actual type T' which failed to have a type member
with the name `M'. This is not terribly different from the rules regarding
compatability of actual and formal arguments in function calls (i.e. you get
an error if you call a function with the wrong types of actual arguments).
So, as in the case of function declarations, I believe that this "instantiation
constraint" should physically appear within somewhere within the list of
template formals, because this constraint is (in effect) a part of the
"interface" which this template definition exports to all would-be
instantiators.
Having this "instantiation constraint" appear within the list of template
formals might also prove valuable in cases where a given translation unit
contains only a declaration of the template, but not a definition, as in:
template <class T { class M; }> void template_function (T);
In such cases, if an attempt were made (within this translation unit) to
instantiate this template with a type which DID NOT have a type member
called `M', the compiler could easily see (as compile-time) that the
instantiation attempt was erroneous, and could issue an accurate diagnostic
for the instantiation attempt right then and there. Unfortunately, all
of the alternative notations I have seen suggested involve placing some
indication of the "typeness" of template formal type members within the
body of the template definition... and any such solution would FORCE
all implementations to wait until template instantiation time (which may,
in many cases be the same as "link-time") before issuing the required
diagnostic for the bogus instantiation attempt.
(It is a fairly well known fact that it is often hard, if not impossible to
produce link-time diagnostics which point the user back to the original
source file and original source line which is really causing the problem.
Therefore, if given the choice, I would always opt for a language design
which makes it possible to generate a maximal number of the required
diagnostics at compile-time rather than putting everything off until link-
time.)
--
-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
Author: dsb@duke.cs.duke.edu (Scott Bigham)
Date: 6 Aug 93 18:47:44 GMT Raw View
In article <rfgCBAw1F.7Hx@netcom.com>, Ronald F. Guilmette
(rfg@netcom.com) suggests the following syntax extension to implement
compile-time-enforceable template constraints:
> int a;
>
> template <class T { class M; }> void template_function (T arg)
> {
> T::M (a); // declaration; not a call
> }
An interesting proposal, and one which raises a number of questions:
- Would the following (IMHO intuitive) constraints also be allowed?
template <class T { int required_data_member; }> void F(T);
template <class T { void required_member_fn(void); }>
void G(T);
template <class T { void parametrized_constraint(T); }>
void H(T);
template <class T { T another_parametrized_constraint; }>
void I(T);
template <class T { T operator + (const T &); }> void J(T);
template <class T { class Multiple; class Constraints; }>
void K(T);
template <class T: public Constrain_By_Base_Class> void L(T);
// and would indirect derived classes satisfy this constraint?
- How does access control affect constraint satisfaction? For instance,
given:
class A { private: typedef int M; };
template <class T { class M; }> void f(T);
void h(A an_A)
{
f(an_A); // legal?
}
Does it matter whether f() is a friend of class A?
- Presumably, constraints would have to match between declaration,
definition and use. What, then, constitutes a match?
template <class T { int i; char *j; }> void f(T);
template <class T { char *j; int i; }> void f(T) {} // legal?
class B { char *j; int i; };
class C { int i; double k; char *j; };
void h(B a_B, C a_C)
{
f(a_B); // legal?
f(a_C); // legal?
}
- Would it be worthwhile to provide a facility for defining an alias
for a list of constraints, to simplify situations like this:
template <class T { /* lots of constraints */ }> class fred {
void member_fn(T);
};
template <class T { /* lots of constraints */ }>
void fred::member_fn(T)
{
// ...
}
or would this simply be a job for the preprocessor?
All in all, I think the proposal has much potential. These questions,
and probably others like them, will likely have to be addressed before
incorporation into the Standard, but otherwise, I think it fits nicely
into the language.
-sbigham
--
Scott Bigham | The opinions expressed above are
dsb@cs.duke.edu | (c) 1993 Hacker Ltd. and cannot be
| copied or distributed without a
| Darn Good Reason(tm).
Author: chased@rbbb.Eng.Sun.COM (David Chase)
Date: 7 Aug 1993 02:11:42 GMT Raw View
In article <rfgCBAw1F.7Hx@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>Regarding the problem of syntax checking of templates...
>I have already (informally) suggested what I feel is a convenient and
>intutively obvious notation for indicating which members of template
>formal type arguments are themselves types. It neither introduces
>new keywords nor involves any conflicts with any existing syntax.
>Here is a brief example:
> int a;
>
> template <class T { class M; }> void template_function (T arg)
> {
> T::M (a); // declaration; not a call
> }
>Note that in this example, it would be erroneous for this template to be
>instantiated with some actual type T' which failed to have a type member
>with the name `M'.
>Having this "instantiation constraint" appear within the list of template
>formals might also prove valuable in cases where a given translation unit
>contains only a declaration of the template, but not a definition, as in:
> template <class T { class M; }> void template_function (T);
Is there any particular reason why you wouldn't extend this to include
more than just type constraints? For example, you could also specify
that a class had to have certain member functions, or you could
specify that a class had to have certain members. For example:
template <class T { unsigned hash(T);
T();
~T();
int operator==()(T,T);
} > class Htable {
private:
/* stuff that I'd like to hide. */
public:
Htable();
~Htable();
int is_in(T&); /* zero if not, else a small integer cookie */
int put_in(T&);
void take_out(T&);
} ;
Obviously, the class T used to instantiate the a Htable<T> could have
more members, and they could appear in a different order. It would be
a handy thing to require that only those class argument methods listed
in the template declaration could be used in the template
implementation. This would return us to a world of separate
compilation and compile-time error reporting. It also enables (but
does not require) a more compact implementation of templates --
instead of something like textual expansion, a table of function
addresses, virtual function indices, and member offsets could be used
instead, and no additional code would need to be generated (it might
run more slowly, of course).
With any luck, some bright person on the committee has already
proposed this.
David Chase
Sun (speaking for myself, as usual)
Author: dag@control.lth.se (Dag Bruck)
Date: 9 Aug 1993 06:37:58 GMT Raw View
In <comp.std.c++> chased@rbbb.Eng.Sun.COM (David Chase) writes:
>In article <....> rfg@netcom.com (Ronald F. Guilmette) writes:
>>Here is a brief example:
>> template <class T { class M; }> void template_function (T);
>
>Is there any particular reason why you wouldn't extend this to include
>more than just type constraints?
>
> template <class T { unsigned hash(T);
> T();
> ~T();
> int operator==()(T,T);
> } > class Htable { .....
> } ;
I think this is absolutely hideous :-) I really don't want to read
template argument lists like that. However, I think you could do it
as a two-step process by first declaring a template-argument-template,
if you excuse the pun:
class T_templ {
unsigned hash(T);
T();
~T();
int operator==()(T,T);
};
template <class T : T_templ > class Htable { .....
} ;
So the idea is that you specify the minimum interface in a separate
class declaration, and then only list the class name(s) in the
template argument list. There are two main advantages:
- the template argument lists is kept reasonably short
- it is easy to see that a group of template classes or
template functions have the same constraints, because
the all refer to the same name. It is also easier to
tell if two type arguments have the same constraints.
Anyone cares to comment?
-- Dag