Topic: Template parameters


Author: Roman Lechtchinsky <wolfro@cs.tu-berlin.de>
Date: 1999/07/05
Raw View
Hi,

I have some problems with figuring out the scope of template parameters.
In 14.1 paragraphs 13 and 14 the standard defines how a template
parameter can be used in the declarations of other template parameters.
However, it seems to allow the following:

template<class T = T> class Foo;

Is this allowed and if so, what does this mean?

Besides, 14.1/13 says that "The scope of a template-parameter extends
from its point of declaration until the end of its template". However,
14.5.2/1 says "A member template ... shall be specified with the
template-parameters of the class template followed by the
template-parameters of the member template". Does this mean that these
parameters are visible only in the respective templates? In particular,
is the following allowed?

template<class T> class Foo {
 template<class T> class Bar;
};

template<class T> template<class T> class Foo<T>::Bar<T> {...};

Bye

Roman
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: wmm@fastdial.net
Date: 1999/07/06
Raw View
In article <3780109D.CE4BA6C7@cs.tu-berlin.de>,
  Roman Lechtchinsky <wolfro@cs.tu-berlin.de> wrote:
> In 14.1 paragraphs 13 and 14 the standard defines how a template
> parameter can be used in the declarations of other template
parameters.
> However, it seems to allow the following:
>
> template<class T = T> class Foo;
>
> Is this allowed and if so, what does this mean?

Congratulations, you have found a genuine defect in the Standard.
J16+WG21 decided at the April, 1999 meeting that it was a defect
and that the wording should be amended in the forthcoming Technical
Corrigendum to forbid use of a template parameter in its own default
argument (see issue 22 on the Core Language issues list).

> Besides, 14.1/13 says that "The scope of a template-parameter extends
> from its point of declaration until the end of its template". However,
> 14.5.2/1 says "A member template ... shall be specified with the
> template-parameters of the class template followed by the
> template-parameters of the member template". Does this mean that these
> parameters are visible only in the respective templates? In
particular,
> is the following allowed?
>
> template<class T> class Foo {
>  template<class T> class Bar;
> };
>
> template<class T> template<class T> class Foo<T>::Bar<T> {...};

No, that is not allowed.  A template declaration is a declarative
region (3.3), and a name in a nested declarative region hides the
same name from an outer declarative region (3.3.7), so the second
T hides the first T.  That means that the T in Foo<T> is the second
T, not the first.  This violates the requirement in 14.5.1p3 that
"The template argument list following the class template name in
the member definition shall name the parameters in the same order
as the one used in the template parameter list of the member."  In
this case, the template argument list following the class template
name doesn't name the parameter at all.  In other words, this is
as if your example were written

  template<class T> template<class T2> class Foo<T2>::Bar<T2> {...};

--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Roman Lechtchinsky <wolfro@cs.tu-berlin.de>
Date: 1999/07/06
Raw View
wmm@fastdial.net wrote:
>
> > template<class T> template<class T> class Foo<T>::Bar<T> {...};
>
> No, that is not allowed.  A template declaration is a declarative
> region (3.3), and a name in a nested declarative region hides the
> same name from an outer declarative region (3.3.7), so the second
> T hides the first T.  That means that the T in Foo<T> is the second
> T, not the first.  This violates the requirement in 14.5.1p3 that
> "The template argument list following the class template name in
> the member definition shall name the parameters in the same order
> as the one used in the template parameter list of the member."  In
> this case, the template argument list following the class template
> name doesn't name the parameter at all.  In other words, this is
> as if your example were written
>
>   template<class T> template<class T2> class Foo<T2>::Bar<T2> {...};

I don't really understand what the sentence you quoted means in this
case. It talks about "the template parameter list of the member"; isn't
that template<class T2> in this example, which doesn't mention T at all?
Besides, if it really forbids the above, what about

template<class T> template<class T2> class Foo<T>::Bar<T>?

Since 14.5.1/3 only mentions Foo's arguments, wouldn't this be allowed?
Anyway, both examples look rather like partial specializations so does
it cover this case at all?

Bye

Roman
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Salters <msalters@lucent.com>
Date: 1999/07/06
Raw View
Roman Lechtchinsky wrote:

> Hi,

> I have some problems with figuring out the scope of template parameters.
> In 14.1 paragraphs 13 and 14 the standard defines how a template
> parameter can be used in the declarations of other template parameters.
> However, it seems to allow the following:

> template<class T = T> class Foo;

> Is this allowed and if so, what does this mean?

You quoted the important part:  " how a template parameter can be used
 in the declarations of __other__ template parameters" (emphasis mine)

e.g. template <typename T, int bufsize = sizeof(T) > class Foo {

> Besides, 14.1/13 says that "The scope of a template-parameter extends
> from its point of declaration until the end of its template". However,
> 14.5.2/1 says "A member template ... shall be specified with the
> template-parameters of the class template followed by the
> template-parameters of the member template". Does this mean that these
> parameters are visible only in the respective templates? In particular,
> is the following allowed?

> template<class T> class Foo {
>         template<class T> class Bar;
> };

The first T has (as defined above) a scope to the ';'. You did quote
the appropriate rule. It does mean that the second T is at a place
where another template paramete T is in scope, thus this is an error

> template<class T> template<class T> class Foo<T>::Bar<T> {...};

And this is the same error. Again the first T has a scope up to the ';'

HTH,

Michiel Salters
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: wmm@fastdial.net
Date: 1999/07/07
Raw View
In article <378209BE.6B9F204E@cs.tu-berlin.de>,
  Roman Lechtchinsky <wolfro@cs.tu-berlin.de> wrote:
> wmm@fastdial.net wrote:
> >
> > > template<class T> template<class T> class Foo<T>::Bar<T> {...};
> >
> > No, that is not allowed.  A template declaration is a declarative
> > region (3.3), and a name in a nested declarative region hides the
> > same name from an outer declarative region (3.3.7), so the second
> > T hides the first T.  That means that the T in Foo<T> is the second
> > T, not the first.  This violates the requirement in 14.5.1p3 that
> > "The template argument list following the class template name in
> > the member definition shall name the parameters in the same order
> > as the one used in the template parameter list of the member."  In
> > this case, the template argument list following the class template
> > name doesn't name the parameter at all.  In other words, this is
> > as if your example were written
> >
> >   template<class T> template<class T2> class Foo<T2>::Bar<T2> {...};
>
> I don't really understand what the sentence you quoted means in this
> case. It talks about "the template parameter list of the member";
isn't
> that template<class T2> in this example, which doesn't mention T at
all?

Unfortunately, this particular passage uses confusing terminology
when the member being defined is itself a template.  What it really
intended to say was "the template parameter list of the member
_definition_."  (Which is clear from the example in the Standard --
it's the "template <...>" clause that introduces the member
definition.)

The point is that the argument list in the nested-name-specifier
in the member definition must match the corresponding parameter
list, and it doesn't in your example.

> Besides, if it really forbids the above, what about
>
> template<class T> template<class T2> class Foo<T>::Bar<T>?
>
> Since 14.5.1/3 only mentions Foo's arguments, wouldn't this be
allowed?

No, that declares a specialization of Bar, and you can't do that
if the containing template isn't specialized (14.7.3p18).

> Anyway, both examples look rather like partial specializations so does
> it cover this case at all?

No, a partial specialization must have one or more template parameters
of its own, and this doesn't.  It's a complete specialization, but
it doesn't use the empty parameter list ("template <>") and so is
not allowed.

One more problem with your original example that I overlooked until
now: 15.6.1p4 says "A template-parameter shall not be redeclared
within its scope (including nested scopes)."  That applies to both
the outer class definition and the member class definition.

--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: mansionj@lonnds.ml.com (James Mansion LADS LDN X4923)
Date: 1995/08/17
Raw View
Given:

template <size_t N> class Foo { public: Foo() ; /*...*/ }

And:

enum { a = 1024 } ;
#define b 1024
#define c size_t(1024)

No prises for guessing that:

Foo<c> f1 ;

is OK.

But what about these?

Foo<a> f2 ;
Foo<b> f3 ;

James

(Only 'c' works with my Sun compiler.  It seems unwilling to perform even the
basic int conversions)
---
[ 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. ]