| 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 |