Search code examples
c++gccclanglanguage-lawyertypename

typename, type members and non-type members: is it valid code?


Consider the following code:

struct S {
    struct type {};
    type type;
};

int main() {  
    typename S::type t;
    (void) t;
}

Apart for the fact that is far from being a good idea, I was experimenting after having read another question here on SO.
I found that the snippet above is compiled with no errors by GCC and it is rejected by clang 3.9 with the following error:

error: typename specifier refers to non-type member 'type' in 'S'

I suspect that clang is right in this case and GCC is wrong (actually, I'm opening an issue to the latter).
Is it the right conclusion or is that a valid use of typename?


Note: I'm not asking how to solve it, I know how to do that. I'm asking only if this code is valid or not.


Solution

  • [temp.res]/4:

    The usual qualified name lookup is used to find the qualified-id even in the presence of typename.

    That is, unlike the case with elaborated-type-specifiers, the name lookup in this case does not ignore non-type names.

    [temp.res]/3:

    If the qualified-id in a typename-specifier does not denote a type or a class template, the program is ill-formed.

    So the program in question is ill-formed.

    [temp.res]/4 also has an example for this:

    struct A {
      struct X { };
      int X;
    };
    struct B {
      struct X { };
    };
    template<class T> void f(T t) {
      typename T::X x;
    }
    void foo() {
      A a;
      B b;
      f(b);             // OK: T::X refers to B::X
      f(a);             // error: T::X refers to the data member A::X not the struct A::X
    }