different way in name lookup with template class

Let's see this two codes:

#include <iostream>
using namespace std;

template <typename T>
struct Base
{
int i;
};

template <typename T>
struct Derived : public Base<T>
{
int get_i() { return i; }
};
int main(int argc, char *argv[])
{
return 0;
}

compile this code fragment will occur error via g++ 3.4 or later:

g++ test.cpp
test.cpp: In member function ‘int Derived<T>::get_i()’:
test.cpp:13:22: error: ‘i’ was not declared in this scope

It's interesting, let's see  how GNU explain to it:

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.

Which says, that 'get_i()' is in indepedent scope, while the base class and derived class is in depedent scope, so compiler can't refer to variable 'i' in base class.

And the similar code:

// code 2
//

template <typename T>
struct Base
{
int f();
};

template <typename T>
struct Derived : Base<T>
{
int g() { return f(); };
};

also has the same problem.

For more detail, please see: 

http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html#fn-1

posted @ 2012-01-10 17:24  walfud  阅读(179)  评论(0编辑  收藏  举报