On Thu, Feb 7, 2013 at 11:56 AM, Robinson, Paul <span dir="ltr"><<a href="mailto:Paul.Robinson@am.sony.com" target="_blank">Paul.Robinson@am.sony.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
From: Robinson, Paul<br>
<div><div class="h5">> From: Dmitri Gribenko [mailto:<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>]<br>
> > On Wed, Feb 6, 2013 at 10:24 PM, Robinson, Paul<br>
> > <<a href="mailto:Paul.Robinson@am.sony.com">Paul.Robinson@am.sony.com</a>> wrote:<br>
> > > Clang is giving a compile time error on the following test case:<br>
> > ><br>
> > >     template<int V0><br>
> > >     struct T0<br>
> > >     {<br>
> > >         enum { E = V0 };<br>
> > >     };<br>
> > ><br>
> > >     template<int V1><br>
> > >     struct T1<br>
> > >     {<br>
> > >         // The name declared here is the same as the type template<br>
> > >         // declared above.<br>
> > >         static int const T0 = T0<V1>::E;<br>
> > >     };<br>
> > ><br>
> > > with the compile time error:<br>
> > ><br>
> > >     test.cpp:12:35: error: no member named 'E' in the global<br>
> namespace<br>
> > >       static int const T0 = T0<V1>::E;<br>
> ><br>
> > I believe this is correct, the code is parsed as (T0 less-than V1)<br>
> > greater-than ::E.<br>
> ><br>
> > ::T0<V1>::E would do what you want.<br>
> ><br>
> > Dmitri<br>
><br>
> Okay, I see that the point-of-declaration of the int T0 is prior to the<br>
> initializer, so unqualified lookup of the T0 from T0<V1>::E will find<br>
> the int T0.  I guess I was confused by the similar-seeming case where<br>
> struct T0 is not a template, and if we see<br>
>   static int const T0 = T0::E;<br>
> then the T0::E is resolved as a qualified reference to member E of<br>
> struct T0.  But delving deeper into the standard, I guess T0<V1> doesn't<br>
> count as a nested-name-specifier, so I do need the leading :: to get the<br>
> effect I want.<br>
><br>
> Thanks,<br>
> --paulr<br>
<br>
</div></div>I take it back.  Looking at the grammar rules in the standard:<br>
(.opt means optional in the grammar quoted below)<br>
<br>
   5.1.1p8 [expr.prim.general]<br>
   nested-name-specifier:<br>
     ::.opt  type-name ::<br>
<br>
   7.1.6.2p1 [dcl.type.simple]<br>
   type-name:<br>
     simple-template-id<br>
<br>
   14.2p1 [temp.names]<br>
   simple-template-id:<br>
     template-name < template-argument-list.opt ><br>
<br>
so T0<V1> does count as a nested-name-specifier, unless there's some<br>
verbiage I didn't notice that excludes this case in the above context.<br></blockquote><div><br></div><div>T0 is not a template-name here, because name lookup finds the static data member. See [temp.names]p1-p3.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I did consider the rule in 3.4p2 [basic.lookup]<br>
  A name "looked up in the context of an expression" is looked up as<br>
  an unqualified name in the scope where the expression is found.<br>
<br>
But, that would exclude the non-template T0::E example, which<br>
clearly handles T0 as a nested-name-specifier rather than a sequence<br>
of (static int) T0 followed by (global scope) ::E.<br>
<br>
So why is the non-template T0:: a nested-name-specifier but the<br>
templated T0<V1>:: is not?<br>
<div class="HOEnZb"><div class="h5"><br>
Thanks,<br>
--paulr<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br>