#include <list>
#include <map>
/**
* MRU Cache
*
* contains up to a fixed size of "Most Recently Used" items, where items are assiciated with keys.
* when asked to fetch a value that is not in the cache, HandleNonExistingKeyFetch is called.
* when an item is removed from the cache, HandleItemRelease is called.
* implementor of this cache must provide those methods.
*
*/
template <typename key_type, typename value_type>
class MruCache
{
public:
const int maxLength;
MruCache(int iMaxLength) : maxLength(iMaxLength) { }
inline value_type FetchItem(key_type key) { return __fetch_item(key); }
virtual ~MruCache() { Clear(); }
/**
* clear the cache.
* for every item contained, HandleItemRelease is called.
*/
virtual void Clear() { __clear(); }
protected:
virtual void HandleItemRelease(key_type key, value_type value) { };
virtual value_type HandleNonExistingKeyFetch(key_type key) = 0;
private:
typedef struct _Entry
{
key_type key;
value_type value;
} Entry;
typedef std::list<Entry> EntryList;
EntryList listOfEntries;
/**
* for fast search in the cache. this map contains pointers to iterators in EntryList.
*/
typedef std::map<key_type, void*> ItrPtrMap;
ItrPtrMap mapOfListIteratorPtr;
value_type __fetch_item(key_type key)
{
Entry entry;
//Ошибка бахает на строке ниже, говорит prtItr not found in context
EntryList::iterator* ptrItr = (EntryList::iterator*) mapOfListIteratorPtr[key];
if (!ptrItr)
{
if ( (int)listOfEntries.size() >= maxLength)
{
Entry lruEntry = listOfEntries.back();
HandleItemRelease(lruEntry.key, lruEntry.value);
listOfEntries.pop_back();
delete mapOfListIteratorPtr[lruEntry.key];
mapOfListIteratorPtr.erase(lruEntry.key);
}
entry.value = HandleNonExistingKeyFetch(key);
entry.key = key;
listOfEntries.push_front(entry);
EntryList::iterator* ptrItr = new EntryList::iterator();
*ptrItr = listOfEntries.begin();
mapOfListIteratorPtr[key] = ptrItr;
}
else
{
entry = *(*ptrItr);
listOfEntries.erase(*ptrItr);
listOfEntries.push_front(entry);
*ptrItr = listOfEntries.begin();
}
return entry.value;
}
virtual void __clear()
{
for (ItrPtrMap::iterator i=mapOfListIteratorPtr.begin(); i!=mapOfListIteratorPtr.end(); i++)
{
void* ptrItr = i->second;
EntryList::iterator* pItr = (EntryList::iterator*) ptrItr;
HandleItemRelease( (*pItr)->key, (*pItr)->value );
delete ptrItr;
}
listOfEntries.clear();
mapOfListIteratorPtr.clear();
}
};
STL from win
Вот нашел маздайный код (под Студией 2008) работает. Но пытаюсь запустить под Kdevelop (g++ компилит), и первая ошибка вылетает (в тексте указал), кто знает в чем дело, помогите. Лог, если надо скину, там ошибок много, но хотя бы эту пофиксить
//Source code
Код:
Заранее благодарен
[COLOR=Red]Для начала код оформи как полагается, а там поглядим.[/COLOR] :)
Цитата:
Running "/usr/bin/make -f nbproject/Makefile-Debug.mk build/Debug/GNU-Linux-x86/Codenet_list.o" in /home/jail/NetBeansProjects/Codenet_MruCashe
mkdir -p build/Debug/GNU-Linux-x86
g++ -c -g -o build/Debug/GNU-Linux-x86/Codenet_list.o Codenet_list.cc
Codenet_list.cc: In member function ‘value_type MruCache<key_type, value_type>::__fetch_item(key_type)’:
Codenet_list.cc:65: error: ‘ptrItr’ was not declared in this scope
Codenet_list.cc:65: error: expected primary-expression before ‘)’ token
Codenet_list.cc:65: error: expected `;' before ‘mapOfListIteratorPtr’
Codenet_list.cc:81: error: expected type-specifier
Codenet_list.cc:81: error: expected `;'
Codenet_list.cc: In member function ‘virtual void MruCache<key_type, value_type>::__clear()’:
Codenet_list.cc:97: error: expected `;' before ‘i’
Codenet_list.cc:98: error: expected `;' before ‘i’
Codenet_list.cc:98: error: ‘i’ was not declared in this scope
Codenet_list.cc:101: error: ‘pItr’ was not declared in this scope
Codenet_list.cc:101: error: expected primary-expression before ‘)’ token
Codenet_list.cc:101: error: expected `;' before ‘ptrItr’
make: *** [build/Debug/GNU-Linux-x86/Codenet_list.o] Ошибка 1
Build failed. Exit value 2.
mkdir -p build/Debug/GNU-Linux-x86
g++ -c -g -o build/Debug/GNU-Linux-x86/Codenet_list.o Codenet_list.cc
Codenet_list.cc: In member function ‘value_type MruCache<key_type, value_type>::__fetch_item(key_type)’:
Codenet_list.cc:65: error: ‘ptrItr’ was not declared in this scope
Codenet_list.cc:65: error: expected primary-expression before ‘)’ token
Codenet_list.cc:65: error: expected `;' before ‘mapOfListIteratorPtr’
Codenet_list.cc:81: error: expected type-specifier
Codenet_list.cc:81: error: expected `;'
Codenet_list.cc: In member function ‘virtual void MruCache<key_type, value_type>::__clear()’:
Codenet_list.cc:97: error: expected `;' before ‘i’
Codenet_list.cc:98: error: expected `;' before ‘i’
Codenet_list.cc:98: error: ‘i’ was not declared in this scope
Codenet_list.cc:101: error: ‘pItr’ was not declared in this scope
Codenet_list.cc:101: error: expected primary-expression before ‘)’ token
Codenet_list.cc:101: error: expected `;' before ‘ptrItr’
make: *** [build/Debug/GNU-Linux-x86/Codenet_list.o] Ошибка 1
Build failed. Exit value 2.
Тут самые "главные" ошибки, на которые стоит обратить внимание ->
[COLOR=Magenta]Codenet_list.cc:65: error: ‘ptrItr’ was not declared in this scope
Codenet_list.cc:98: error: ‘i’ was not declared in this scope
Codenet_list.cc:101: error: ‘pItr’ was not declared in this scope[/COLOR]
Все остальное вытекает из них.
Обрати внимание на конструкции: EntryList::iterator* ptrItr and ItrPtrMap::iterator i. Загляни в хидеры list и map, а так же algoritm.
Скажу тебе более того, тут дело не в компиляторе (если ты вдруг на него подумал). Я компилил твой пример на Solaris с Sun'кими компилерами, результат вточь такой же, а значит компилер можешь смело исключать. Разбираться времени нет, дерзай сам. :)