template and disambiguation 
July 22nd, 2005, 10:19 AM
| | | template and disambiguation
The new version of GCC is out and in its list of changes, it talks about the
C++ Standard's requirements for using the typename and template keywords to
disambiguate dependent names. I'm use to seeing typename being used, but
I've never seen template used for this purpose. I've studied there example
for a long time, and still don't understand what situations call for the
template keyword (and reading the standard, to me, is Greek). Can some
explain this. The GCC example follows:
You must now use the typename and template keywords to disambiguate
dependent names, as required by the C++ standard.
struct K {
typedef int mytype_t;
};
template <class T1> struct A {
template <class T2> struct B {
void callme(void);
};
template <int N> void bar(void)
{
// Use 'typename' to tell the parser that T1::mytype_t names
// a type. This is needed because the name is dependent (in
// this case, on template parameter T1).
typename T1::mytype_t x;
x = 0;
}
};
template <class T> void template_func(void)
{
// Use 'template' to prefix member templates within
// dependent types (a has type A<T>, which depends on
// the template parameter T).
A<T> a;
a.template bar<0>();
// Use 'template' to tell the parser that B is a nested
// template class (dependent on template parameter T), and
// 'typename' because the whole A<T>::B<int> is
// the name of a type (again, dependent).
typename A<T>::template B<int> b;
b.callme();
}
void non_template_func(void)
{
// Outside of any template class or function, no names can be
// dependent, so the use of the keyword 'typename' and 'template'
// is not needed (and actually forbidden).
A<K> a;
a.bar<0>();
A<K>::B<float> b;
b.callme();
} | 
July 22nd, 2005, 10:20 AM
| | | Re: template and disambiguation
Xenos wrote:[color=blue]
>
> The new version of GCC is out and in its list of changes, it talks about the
> C++ Standard's requirements for using the typename and template keywords to
> disambiguate dependent names. I'm use to seeing typename being used, but
> I've never seen template used for this purpose. I've studied there example
> for a long time, and still don't understand what situations call for the
> template keyword (and reading the standard, to me, is Greek). Can some
> explain this. The GCC example follows:
>
> You must now use the typename and template keywords to disambiguate
> dependent names, as required by the C++ standard.
>
> template <class T> void template_func(void)
> {
> // Use 'template' to prefix member templates within
> // dependent types (a has type A<T>, which depends on
> // the template parameter T).
> A<T> a;
> a.template bar<0>();
>
> // Use 'template' to tell the parser that B is a nested
> // template class (dependent on template parameter T), and
> // 'typename' because the whole A<T>::B<int> is
> // the name of a type (again, dependent).
> typename A<T>::template B<int> b;
> b.callme();
> }
>
> void non_template_func(void)
> {
> // Outside of any template class or function, no names can be
> // dependent, so the use of the keyword 'typename' and 'template'
> // is not needed (and actually forbidden).
> A<K> a;
> a.bar<0>();
> A<K>::B<float> b;
> b.callme();
> }[/color]
To paraphrase it again:
You have to use the template construct when you have things like the following:
dependent_name::template nested_template_id
dependent_name.template nested_template_id
dependent_name->template nested_template_id
where
dependent_name is the name of a class template that depends on a
template parameter. In the snippet above, in template_func(void),
A<T> and a are dependent names.
nested_template_id is a function template or class template name,
B<int>, B<T1>, f<int>(), f<T1>().
Why you need it? If you don't give it, the compiler will treat the "<"
in nested_template_id as a less_than operator. It will not attempt to find
out that B or f are actually templates; the compiler's default behaviour is
to assume they are not. AFAIK, the reason for that is that B or f can be
declared and defined in any particular specialization of the class corresponding
to the dependent_name, not necessarily in the "original" template definition.
What is more, a specialization can redefine them altogether, e.g. make them
non-templates.
The key point here is the "dependent_name". A compiler, generally,
cannot assume it knows the nested definitions of a dependent name.
On the other hand, in the last example above (non_template_func(void)), A<K> and
a are not dependent names. The compiler now deals with a specialization
and, therefore, it knows that B and bar are template ids. Thus, conceptually,
there is no need to give it a "template" hint in this case (the current standard
would not allow it anyway (again AFAIK), but there are opinions that it should,
for symmetry).
Denis | 
July 22nd, 2005, 10:20 AM
| | | Re: template and disambiguation
"Xenos" <dont.spam.me@spamhate.com> wrote in message news:<c6p3tp$sjq5@cui1.lmms.lmco.com>...[color=blue]
> The new version of GCC is out and in its list of changes, it talks about the
> C++ Standard's requirements for using the typename and template keywords to
> disambiguate dependent names. I'm use to seeing typename being used, but
> I've never seen template used for this purpose. I've studied there example
> for a long time, and still don't understand what situations call for the
> template keyword (and reading the standard, to me, is Greek). Can some
> explain this. The GCC example follows:
>[/color]
Without going into too much detail or quoting directly from the
standard, I think there are a few clarifications that might help you.
1) the template and typename keywords are only need inside
declarations and definitions of other templated types.
2) Typename is needed because the compiler cannot know when a type
parameter of a template is used as a identifier (e.g. T::A ), whether
it is referring to a type name, or being used for scope resolution.
Thus the typename keyword is required in the case when T::A refers to
a type; in all other cases it is assumed to be for scope-resolution.
3) The template keyword is needed for more complicated declarations
when a template parameter
a) is itself a template, e.g. consider the following declarations:
template <class T, class U> class A {
U<T> u; // error: U is not a template type
template <class T, template <class> U > class B {
U<T> u; // this is now ok
};
the second version explicitly informs the compiler that class U
is allowed to be used as a template type within template class B.
b) has a templated member (function or class) ... the examples
from the GCC page pertain to this case.
In both cases, the compiler would otherwise have no way of knowing
that the attempt to use a template parameter (or member of a template
parameter) as a template was valid.
Hopefully you can now understand the GCC examples you posted a little
better.
Dave Moore | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 220,662 network members.
|