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.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(){}
};

それはうまくコンパイルされます。

4

2 に答える 2

2

用途typename:

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

その理由iteratorは、テンプレート引数に依存する名前です。その値は、実際にはテンプレート引数であるに依存ますそのため、実際にはではなくネストされたであることをコンパイラに伝える必要があります。CacheListTtypenameiteratorstatic

ただし、2 番目のケースでは、従属名ではありません。

ヨハネスによるこの詳細な説明を読んでください。

于 2011-06-22T00:58:49.780 に答える
1

これを置き換えます:

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

これとともに:

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

この質問を参照してください。基本的に、コンパイラは (テンプレートの引数を知らずに)CacheList::iteratorがインスタンス化時まで型か値かを知りません。それまで決定を延期することは禁じられているため、値であると想定し、それ以外の場合は「ヒント」。

于 2011-06-22T01:00:32.847 に答える