> I also read a link you provided, but how can I know that current is a dependent name in this program?
This was linked to from within the link in the earlier post:
In a template that we write, there are two kinds of names (identifiers) that could be used - dependant names and non- dependant names. A dependant name is a name that depends on a template parameter; a non-dependant name has the same meaning irrespective of what the template parameters are.
For example:
1 2 3 4 5
|
template< typename T > void foo( T& x, int value )
{
++ T::static_member_variable ; // 'static_member_variable' is a dependant name
++value ; // 'value' is a non- dependant name
}
|
What a dependant name refers to could be something different for each different instantiation of the template. As a consequence, C++ templates are subject to "two-phase name lookup". When a template is initially parsed (before any instantiation takes place) the compiler looks up the non-dependent names. When a particular instantiation of the template takes place, the template parameters are known by then, and the compiler looks up dependent names. |
http://www.cplusplus.com/forum/beginner/103508/#msg557627
In our case, we know that the name '
current', used in the definition of a member of
List<T>::iterator is a dependent name. It refers to the name in the base class
List<T>::const_iterator (of type 'pointer to
List<T>::Node), which is dependant on the template parameter
T.
However, when a dependent name refers to a name in a base class, the compiler needs to be informed that it is a dependent name. This is so, because the IS specifies:
In the definition of a class or class template, the scope of a dependent base class is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. |
For instance:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
int name_one = 0 ;
template < typename T > struct base { int name_one = 0 ; int name_two = 0 ; } ;
template < typename T > struct derived : base<T>
{
void foo()
{
name_one = 7 ; // 'name_one' is treated as a non-dependant name
// (the scope of the dependent base class base<T> is not examined)
// assigns to ::name_one at namespace scope (and not to base<T>::name_one)
// name_two = 7 ; // **** error: 'name_two' is not found
// we can fix the error in several ways
base<T>::name_two = 7 ; // fine: 'name_two' is a dependant name in the dependent base class
derived<T>::name_two = 7 ; // fine: 'name_two' is a dependant name, to be looked up during phase two
this->name_two = 7 ; // fine: same as above
using name_two = base<T>::name_two ; // when we use the unqualified name 'name_two'
// we mean the dependant name 'name_two' in the dependent base class
name_two = 7 ; // fine: refers to the dependant name 'base<T>::name_two' ;
}
};
|
> This program is not written by me. It has been taken from my CS professor's reading assignment.
Did he/she/it actually dump a
using namespace std; in the header file?
And favoured <stddef.h> over <cstddef> and then blithely proceeded to sprinkle
NULL liberally all over the code?
Career teacher, I suppose. This is the fundamental tragedy of C++:
those who can, do; those who can't (with a few notable exceptions) teach.
(At least in the US and (alas) in my own country. Perhaps things are not as bad elsewhere. In this regard, I do envy the education system of the medical profession.)