------- Additional Comments From sebor at roguewave dot com 2005-04-19 15:39 ------- I discussed this with Mike Miller of EDG. His response to my query on the issue (copied with his permission) is below.
Mike Miller wrote: ... > There were a couple of different examples in that thread, > so just to avoid confusion, here's the one I'll refer to: > > struct A { > int foo_; > }; > template <typename T> struct B: public A { }; > template <typename T> struct C: B<T> { > int foo() { > return A::foo_; // #1 > } > }; > > The question is how the reference on line #1 is treated. Wolfgang's > analysis isn't quite right. While it's true that "A" is non-dependent > and thus is bound to ::A at template definition time, that is > irrelevant. When C<int>::foo() (for instance) is instantiated, it turns > out that the reference to ::A::foo_ is, in fact, a non-static member of > a base class (9.3.1p3), so the reference is transformed into > (*this).::A::foo_ and there is no error. This is not a violation of > 14.6.2p3 -- there's no lookup in a dependent base class involved, as > Wolfgang's comments assume, and the description "the access is assumed > to be from the outside, not within the class hierarchy through this->" > doesn't accurately describe how 9.3.1p3 works. > > In fact, though, this just sort of happens to work because A is both > visible in the definition context and a base class of the instantiated > template. If you add an explicit specialization > > template<> struct B<int> { }; > > as suggested in Andrew's comment, so A is not a base class, or if you > change the program so that A is not visible in the definition context > (by making it a member of a namespace, for instance), we do report an > error in the instantiated C<int>::foo(). (There's no requirement to > report errors in uninstantiated templates, of course, contrary to > Andrew's observation.) > > This is sort of contrary to the "spirit" of two-stage lookup, though -- > Wolfgang's expectation is not unreasonable, I think, even though the > details of his reasoning are incorrect. I'm probably going to open a > core issue on this, especially in light of the differences between > implementations. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21008