template and disambiguation

Discussion in 'C++' started by Xenos, Apr 28, 2004.

  1. Xenos

    Xenos Guest

    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();
    }
    Xenos, Apr 28, 2004
    #1
    1. Advertising

  2. Xenos wrote:
    >
    > 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();
    > }


    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
    Denis Remezov, Apr 29, 2004
    #2
    1. Advertising

  3. Xenos

    Dave Moore Guest

    "Xenos" <> wrote in message news:<c6p3tp$>...
    > 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:
    >


    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
    Dave Moore, Apr 29, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Collins

    Template disambiguation

    John Collins, Dec 28, 2004, in forum: C++
    Replies:
    1
    Views:
    455
    Victor Bazarov
    Dec 29, 2004
  2. =?windows-1250?Q?Petr_Jake=9A?=
    Replies:
    11
    Views:
    1,507
  3. Nomen Nescio

    User error or g++ disambiguation bug?

    Nomen Nescio, Aug 21, 2007, in forum: C Programming
    Replies:
    10
    Views:
    572
    CBFalconer
    Aug 24, 2007
  4. Replies:
    1
    Views:
    319
    Duane Hebert
    Aug 21, 2007
  5. bonzo
    Replies:
    1
    Views:
    311
    bonzo
    Oct 15, 2008
Loading...

Share This Page