Не могу определить шаблонные типы для моего класса LruCache
#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(){}
};
если я попробую просто
Кеш LruCache;
Я получаю следующую ошибку компиляции:
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
Однако, если я определю класс без шаблонных типов. т.е.
class LruCache
{
private:
typedef std::pair< int, int > EntryPair;
typedef std::list< EntryPair > CacheList;
typedef std::map< int, CacheList::iterator > CacheMap;
public:
LruCache(){}
~LruCache(){}
};
Компилируется просто отлично.
2 ответа
Использование typename
как:
typedef std::map< K,typename CacheList::iterator > CacheMap;
//^^^^^^
Это потому что iterator
является зависимым именем аргумента шаблона. Его стоимость зависит от CacheList
что в свою очередь зависит от T
который на самом деле является аргументом шаблона. Поэтому typename
это необходимо здесь, который говорит компилятору, что iterator
на самом деле вложенный тип, а не static
значение
Однако во втором случае это не зависимое имя.
Прочитайте подробное объяснение Йоханнеса:
Заменить это:
typedef std::map< K, CacheList::iterator > CacheMap;
с этим:
typedef std::map< K, typename CacheList::iterator > CacheMap;
Смотрите этот вопрос. По сути, компилятор не знает (не зная аргументов шаблона), CacheList::iterator
является типом или значением до времени создания экземпляра, и запрещается откладывать решение до тех пор, поэтому предполагается, что это значение, и в противном случае вы должны дать ему "подсказку".