#include <map>
#include <list>
template < typename K, typename V>
class LruCache
{
private:
typedef std::pair< K, V > EntryPair;
typedef std::list< EntryPair > CacheList;
typedef std::map< K, CacheList::iterator > CacheMap;
public:
LruCache(){}
~LruCache(){}
};
if I try simply
LruCache cache;
I get the following compilation error:
LruCache.h:17:46: error: type/value mismatch at argument 2 in template parameter list for ‘template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map’
LruCache.h:17:46: error: expected a type, got ‘LruCache<K, V>::CacheList:: iterator’
LruCache.h:17:46: error: template argument 4 is invalid
However, if I define the class without template types. i.e.
class LruCache
{
private:
typedef std::pair< int, int > EntryPair;
typedef std::list< EntryPair > CacheList;
typedef std::map< int, CacheList::iterator > CacheMap;
public:
LruCache(){}
~LruCache(){}
};
It compiles just fine.
Use typename
as:
typedef std::map< K,typename CacheList::iterator > CacheMap;
//^^^^^^
Its because iterator
is a dependent name on the template argument. Its value depends on CacheList
which in turn depends on the T
which is in fact a template argument. That is why typename
its needed here which tells the compiler that iterator
is actually a nested type, not static
value.
However, in the second case, its not a dependent name.
Read this detail explanation by Johannes: