Re: anti-standard code can compile -- about template class
George <George@discussions.microsoft.com> wrote:
I have tried if we try to instantise the code I posted in my original
question, it can not compile. Here is my code.
Then I guess the conformance has improved in later versions. I only have
VC7.1 handy at the moment to check, and your code compiles there.
Does this compile error
because of VC will look for global i other than base class i?
That's what a conforming compiler should do, yes.
I do
not know why if the class is instantised, still the global i other
than base class i is looked for?
Unqualified name that's not part of a member access expression (as in
something.name or something->name) is not considered a dependent name.
Thus, it is looked up when template definition is processed, not when
the template is instantiated (I'm assuming a compiler that properly
implements two-phase lookup; at least some MSVC versions don't). A side
effect of this is that the name is not looked up in the base class if
the base class is itself a template (the compiler cannot look inside a
template until its parameters are known, because there might be
specializations).
This is why in your example member variable Base<T>::i is not found by
name lookup.
template <typename T> struct Base {
public:
Base (int _i): i (_i)
{
}
int i;
};
template <typename T> struct Derived : public Base<T> {
public:
Derived (int _i) : Base<T> (_i)
{
}
int get_i() { return i; }
};
Make it
int get_i() { return this->i; }
// or
int get_i() { return Base<T>::i; }
The first variant is more common. Both turn 'i' into a dependent name,
thus delaying lookup until the template is instantiated.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925