------- Additional Comments From sebor at roguewave dot com 2005-04-19 15:41 ------- Here's a followup email from Mike with some calarifying comments:
Mike Miller wrote: > Martin Sebor wrote: > >> Thanks a lot for the detailed analysis! I wonder if your reasoning >> would be the same given a slightly different test case (one that's >> closer to the original in comment #1): >> >>> >>> struct A { >> >> >> protected: // <<< ADDED <<< >> >>> int foo_; >>> }; >>> template <typename T> struct B: public A { }; >>> template <typename T> struct C: B<T> { >>> int foo() { >>> return A::foo_; // #1 >>> } >>> }; > > > No, I don't think that changes things. Again, the situation is the > same: whether A is the global class or the injected-class-name doesn't > affect whether C<int> (or whatever) has access to A::foo_. (There are > cases where it does matter, but this isn't one of them. Those typically > involve private or protected inheritance, where the access from > "outside" is greater than the inherited access.) > > The general principle is that non-dependent names are looked up and > bound in the definition context (14.6.3), but that's really the only > semantic effect. In cases like this one, it's as if "A" were replaced > by "::A". If the result of using "::A" is well-formed, then the version > with just "A" is, too. > >> But if an implementation is permitted to diagnose access violations >> at definition time wouldn't the gcc compilation error be justified? > > > I think the general rule is that you should only issue a diagnostic if > you can tell that no well-formed instantiation is possible (14.6p7). In > these cases, at least some specializations will have well-formed > instantiations, so no diagnostic is permitted. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21008