2013-06-20 2 views
0

C++에서 LRU 캐시를 구현해야합니다. 이 코드를 가지고 컴파일하는 동안 나는 문제가있다 :C++에서 LRU 캐시 구현 - 컴파일 오류

#include <iostream> 
#include <vector> 
#include <hash_map> 

using namespace std; 
using namespace stdext; 

template<class K, class T> 
struct LRUCacheEntry 
{ 
    K key; 
    T data; 
    LRUCacheEntry* prev; 
    LRUCacheEntry* next; 
}; 

template<class K, class T> 
class LRUCache 
{ 
private: 
    hash_map< K, LRUCacheEntry<K,T>* > _mapping; 
    vector< LRUCacheEntry<K,T>* >  _freeEntries; 
    LRUCacheEntry<K,T> *   head; 
    LRUCacheEntry<K,T> *   tail; 
    LRUCacheEntry<K,T> *   entries; 
public: 
    LRUCache(size_t size){ 
     entries = new LRUCacheEntry<K,T>[size]; 
     for (int i=0; i<size; i++) 
      _freeEntries.push_back(entries+i); 
     head = new LRUCacheEntry<K,T>; 
     tail = new LRUCacheEntry<K,T>; 
     head->prev = NULL; 
     head->next = tail; 
     tail->next = NULL; 
     tail->prev = head; 
    } 
    ~LRUCache() 
    { 
     delete head; 
     delete tail; 
     delete [] entries; 
    } 
    void put(K key, T data) 
    { 
     LRUCacheEntry<K,T>* node = _mapping[key]; 
     if(node) 
     { 
      // refresh the link list 
      detach(node); 
      node->data = data; 
      attach(node); 
     } 
     else{ 
      if (_freeEntries.empty()) 
      { 
       node = tail->prev; 
       detach(node); 
       _mapping.erase(node->key); 
       node->data = data; 
       node->key = key; 
       attach(node); 
      } 
      else{ 
       node = _freeEntries.back(); 
       _freeEntries.pop_back(); 
       node->key = key; 
       node->data = data; 
       _mapping[key] = node; 
       attach(node); 
      } 
     } 
    } 

    T get(K key) 
    { 
     LRUCacheEntry<K,T>* node = _mapping[key]; 
     if(node) 
     { 
      detach(node); 
      attach(node); 
      return node->data; 
     } 
     else return NULL; 
    } 

private: 
    void detach(LRUCacheEntry<K,T>* node) 
    { 
     node->prev->next = node->next; 
     node->next->prev = node->prev; 
    } 
    void attach(LRUCacheEntry<K,T>* node) 
    { 
     node->next = head->next; 
     node->prev = head; 
     head->next = node; 
     node->next->prev = node; 
    } 
}; 

컴파일 resualt :

In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/hash_map:60, 
       from Source.C:3: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/backward_warning.h:28:2: warning: #warning This file includes at least one deprecated or antiquated header which may be removed without further notice at a future date. Please use a non-deprecated interface with equivalent functionality instead. For a listing of replacement headers and interfaces, consult the file backward_warning.h. To disable this warning use -Wno-deprecated. 
Source.C:6: error: âstdextâ is not a namespace-name 
Source.C:6: error: expected namespace-name before â;â token 
Source.C:21: error: ISO C++ forbids declaration of âhash_mapâ with no type 
Source.C:21: error: expected â;â before â<â token 
Source.C: In member function âvoid LRUCache<K, T>::put(K, T)â: 
Source.C:46: error: â_mappingâ was not declared in this scope 
Source.C: In member function âT LRUCache<K, T>::get(K)â: 
Source.C:77: error: â_mappingâ was not declared in this scope 

누군가가 내가 "stdext"문제를 해결할 수있는 방법을 말해 줄 수 있습니까? 난 나머지 오류를 해결할 것 같아요. TNX!

+0

3/5 규칙을 따르지 않고 C++ 11로 업그레이드하면'std :: unordered_map'을 사용할 수 있습니다. ** 헤더에'namespace blah;를 사용하지 마십시오. 'put '과'get'는'operator []'의 일반적인 맵 인터페이스로 대체하는 것이 더 나을 것입니다. – chris

+0

@chris가 말한 것에 더하여, 헤더 파일에'using namespace ... '문을 추가하는 것을 삼가하십시오. 약간 짜증나지만 템플릿 코드에서 네임 스페이스를 사용하면 클래스 이름 충돌을 피할 수 있습니다. –

답변

0

stdext은 MSVC 확장이지만 GCC를 사용하여 Linux에서 컴파일 중이므로 사용할 수 없습니다. GCC는 비슷한 확장자를 가지고 있지만 그 헤더는 ext/hash_map이며 stdext이 아닌 __gnu_cxx 네임 스페이스에 있습니다. MSVC와 GCC의 hash_maps는 비슷한 인터페이스를 가지고 있지만 올바르게 호출했다면 미묘한 차이가 있습니다.

가능한 경우 C++ 11의 unordered_map을 활용하십시오. 그렇지 않으면 TR1을 사용할 수 있고 std::tr1::unordered_map 일 수 있습니다. 마지막으로 Boost의 정렬되지 않은 컨테이너 (TR1 및 C++ 11 인터페이스의 기본 역할을 함)를 고려하십시오.

편집 GCC 4.4.x를 사용하고있는 것으로 나타났습니다. TR1을 사용할 수 있습니다. 유일한 문제는 MSVC가있는 창에서 동일한 코드를 컴파일하는 경우뿐입니다. TR1을 사용할 수 있다고 생각하지 않습니다. (VC8 및 VC9를 사용할 수 있으며 사용할 수 없습니다.) VC10에서 C++ 11 라이브러리 지원을 시작하고 TR1은 완전히 건너 뜁니다.)

+0

TNX 위대한! – user2456678