C++ Can';t为我的LruCache类定义模板类型 #包括 #包括 模板 类LruCache { 私人: typedef std::pairEntryPair; typedef std::listCacheList; typedef std::mapCacheMap; 公众: LruCache(){} ~LruCache(){} };

C++ Can';t为我的LruCache类定义模板类型 #包括 #包括 模板 类LruCache { 私人: typedef std::pairEntryPair; typedef std::listCacheList; typedef std::mapCacheMap; 公众: LruCache(){} ~LruCache(){} };,c++,linux,templates,gcc4,C++,Linux,Templates,Gcc4,如果我简单地尝试 LruCache缓存 我发现以下编译错误: #include <map> #include <list> template < typename K, typename V> class LruCache { private: typedef std::pair< K, V > EntryPair; typedef std::list< EntryPair > CacheList; type

如果我简单地尝试

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.h:17:46:错误:“模板类std::map”的模板参数列表中参数2的类型/值不匹配
LruCache.h:17:46:错误:应为类型,得到'LruCache::CacheList::iterator'
LruCache.h:17:46:错误:模板参数4无效
但是,如果我定义的类没有模板类型。i、 e

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
类LruCache { 私人: typedef std::pairEntryPair; typedef std::listCacheList; typedef std::mapCacheMap; 公众: LruCache(){} ~LruCache(){} };
它编译得很好。

使用
typename
作为:

class LruCache
{
private:
    typedef std::pair< int, int > EntryPair;
    typedef std::list< EntryPair > CacheList;
    typedef std::map< int, CacheList::iterator > CacheMap;

public:
    LruCache(){}
    ~LruCache(){}
};
typedef std::mapCacheMap;
//^^^^^^
这是因为迭代器是模板参数的从属名称。它的值取决于
CacheList
,后者又取决于
T
,后者实际上是一个模板参数。这就是为什么这里需要
typename
,它告诉编译器
iterator
实际上是一个嵌套的类型,而不是
静态的

但是,在第二种情况下,它不是从属名称

请阅读Johannes的详细说明:

替换此:

typedef std::map< K,typename CacheList::iterator > CacheMap;
                   //^^^^^^
typedef std::mapCacheMap;
为此:

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

看。基本上,编译器在实例化之前(不知道模板参数)不知道
CacheList::iterator
是一个类型还是一个值,并且禁止在实例化之前延迟决策,因此它假设它是一个值,您必须给它一个“提示”否则。

编译器不知道CacheList::iterator是类型还是成员。例如,std::string::npos是一个常量成员,而std::vector::iterator是一个类型。由于
CacheList
依赖于模板参数(K和V),编译器猜测CacheList::iterator是一个成员。因为您知道它是一个类型,所以必须告诉编译器。
typedef std::map< K, typename CacheList::iterator > CacheMap;