2011-06-22 19 views
2
#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緩存;

我得到以下編譯錯誤:

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

但是,在第二種情況下,它不是依賴名稱。

約翰內斯閱讀本詳細的解釋:

+1

編譯器不知道CacheList :: iterator是類型還是成員。例如,std :: string :: npos是一個常量成員,但std :: vector :: iterator是一個類型。由於'CacheList'依賴於一個模板參數(你的K和V),編譯器會猜測CacheList :: iterator是一個成員。既然你知道它是一個類型,你必須告訴編譯器。 – Chris

+0

哇,謝謝!對它進行排序。 – Matt

1

替換此:

typedef std::map< K, CacheList::iterator > CacheMap; 

與此:

typedef std::map< K, typename CacheList::iterator > CacheMap; 

小號ee this question。基本上,編譯器不知道(不知道模板參數)CacheList::iterator是否是直到實例化時間的類型或值,並且在此之前禁止推遲決策,因此它假定它是一個值,並且您必須給它否則提示「提示」。