Two-stage name lookup sometimes leads to situations with behavior different from non-template codes. The most common is probably this:
template <typename T> struct Base {
int i;
};
template <typename T> struct Derived : public Base<T> {
int get_i() { return i; }
};
In get_i()
, i
is not used in a dependent context, so the compiler will look for a name declared at the enclosing namespace scope (which is the global scope here). It will not look into the base class, since that is dependent and you may declare specializations of Base
even after declaring Derived
, so the compiler can't really know what i
would refer to. If there is no global variable i
, then you will get an error message.
In order to make it clear that you want the member of the base class, you need to defer lookup until instantiation time, at which the base class is known. For this, you need to access i
in a dependent context, by either using this->i
(remember that this
is of type Derived<T>*
, so is obviously dependent), or using Base<T>::i
. Alternatively, Base<T>::i
might be brought into scope by a using
-declaration.
No comments:
Post a Comment