You can see the the use of typename for declaring templates in List.hpp.

template<typename T>
bool List<T>::empty() const {

When compiling your project, you may get the following kind of error:

$ ./List_tests.exe
./List_tests.cpp:94:8: error: missing 'typename' prior to dependent type name 'List<T>::Iterator'
List<T>::Iterator i;

If you see an error message that talks about missing ‘typename’ prior to dependent type name, simply stick in the keyword “typename” before the type declaration. In the instance above, it would become:

typename List<T>::Iterator i;

The same thing would apply if you declared a loop variable. For example:

for (List<T>::Iterator i; /*...*/)

may need to become (if you get an error from the compiler):

for (typename List<T>::Iterator i; /*...*/)

Discussion of dependent types and why we have to insert the keyword typename is beyond the scope of this course (the reason is quite subtle and deep). If you want to see some explanation, see this article: