[cfe-dev] Error on valid; and q. about using tentative parse
Richard Smith
richard at metafoo.co.uk
Thu Feb 7 13:32:34 PST 2013
On Thu, Feb 7, 2013 at 11:56 AM, Robinson, Paul
<Paul.Robinson at am.sony.com>wrote:
> From: Robinson, Paul
> > From: Dmitri Gribenko [mailto:gribozavr at gmail.com]
> > > On Wed, Feb 6, 2013 at 10:24 PM, Robinson, Paul
> > > <Paul.Robinson at am.sony.com> wrote:
> > > > Clang is giving a compile time error on the following test case:
> > > >
> > > > template<int V0>
> > > > struct T0
> > > > {
> > > > enum { E = V0 };
> > > > };
> > > >
> > > > template<int V1>
> > > > struct T1
> > > > {
> > > > // The name declared here is the same as the type template
> > > > // declared above.
> > > > static int const T0 = T0<V1>::E;
> > > > };
> > > >
> > > > with the compile time error:
> > > >
> > > > test.cpp:12:35: error: no member named 'E' in the global
> > namespace
> > > > static int const T0 = T0<V1>::E;
> > >
> > > I believe this is correct, the code is parsed as (T0 less-than V1)
> > > greater-than ::E.
> > >
> > > ::T0<V1>::E would do what you want.
> > >
> > > Dmitri
> >
> > Okay, I see that the point-of-declaration of the int T0 is prior to the
> > initializer, so unqualified lookup of the T0 from T0<V1>::E will find
> > the int T0. I guess I was confused by the similar-seeming case where
> > struct T0 is not a template, and if we see
> > static int const T0 = T0::E;
> > then the T0::E is resolved as a qualified reference to member E of
> > struct T0. But delving deeper into the standard, I guess T0<V1> doesn't
> > count as a nested-name-specifier, so I do need the leading :: to get the
> > effect I want.
> >
> > Thanks,
> > --paulr
>
> I take it back. Looking at the grammar rules in the standard:
> (.opt means optional in the grammar quoted below)
>
> 5.1.1p8 [expr.prim.general]
> nested-name-specifier:
> ::.opt type-name ::
>
> 7.1.6.2p1 [dcl.type.simple]
> type-name:
> simple-template-id
>
> 14.2p1 [temp.names]
> simple-template-id:
> template-name < template-argument-list.opt >
>
> so T0<V1> does count as a nested-name-specifier, unless there's some
> verbiage I didn't notice that excludes this case in the above context.
>
T0 is not a template-name here, because name lookup finds the static data
member. See [temp.names]p1-p3.
> I did consider the rule in 3.4p2 [basic.lookup]
> A name "looked up in the context of an expression" is looked up as
> an unqualified name in the scope where the expression is found.
>
> But, that would exclude the non-template T0::E example, which
> clearly handles T0 as a nested-name-specifier rather than a sequence
> of (static int) T0 followed by (global scope) ::E.
>
> So why is the non-template T0:: a nested-name-specifier but the
> templated T0<V1>:: is not?
>
> Thanks,
> --paulr
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130207/4985e600/attachment.html>
More information about the cfe-dev
mailing list