Title
Dependent qualified-ids without the typename keyword
Status
cd1
Section
13.8 [temp.res]
Submitter
Daveed Vandevoorde

Created on 2007-12-06.00:00:00 last changed 196 months ago

Messages

Date: 2008-06-15.00:00:00

[Voted into the WP at the June, 2008 meeting.]

Date: 2008-02-15.00:00:00

Proposed resolution (February, 2008):

Add the following after 13.8 [temp.res] paragraph 5:

If, for a given set of template arguments, a specialization of a template is instantiated that refers to a qualified-id that denotes a type, and the nested-name-specifier of the qualified-id depends on a template parameter, the qualified-id shall either be prefixed by typename or shall be used in a context in which it implicitly names a type as described above. [Example:

    template <class T> void f(int i) {
      T::x * i;     // T::x must not be a type
    }

    struct Foo {
      typedef int x;
    };

    struct Bar {
      static int const x = 5;
    };

    int main() {
      f<Bar>(1);     // OK
      f<Foo>(1);     // error: Foo::x is a type
    }

end example]

Date: 2008-07-27.00:00:00

13.8 [temp.res] paragraphs 2 and 4 read,

A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.

If a specialization of a template is instantiated for a set of template-arguments such that the qualified-id prefixed by typename does not denote a type, the specialization is ill-formed.

It is not clear whether this is intended to, or is sufficient to, render a specialization ill-formed if a dependent qualified-id that is not prefixed by typename actually does denote a type. For example,

    int i;

    template <class T> void f() {
        T::x * i; // declaration or multiplication!?
    }

    struct Foo {
        typedef int x;
    };

    struct Bar {
        static int const x = 5;
    };

    int main() {
        f<Bar>(); // multiplication
        f<Foo>(); // declaration!
    }

I think that the specialization for Foo should be ill-formed.

History
Date User Action Args
2008-10-05 00:00:00adminsetstatus: dr -> cd1
2008-07-27 00:00:00adminsetmessages: + msg1735
2008-06-29 00:00:00adminsetstatus: ready -> dr
2008-03-17 00:00:00adminsetmessages: + msg1588
2008-03-17 00:00:00adminsetstatus: open -> ready
2007-12-06 00:00:00admincreate