Search code examples
c++vectorstliteratormember-functions

No matching member function to call for 'push_back' error


While implementing LRU cache got this error. Earlier I was implementing it via maps it works then but somehow even when doing it as vector it does not work.

#include <list>
class LRUCache {
    list<pair<int,int>> lru;
    int cap;
    vector<list<pair<int, int>>::iterator> hash;
public:
LRUCache(int capacity) {
    cap = capacity;
    for(int i=0;i<=3000;i++)
        hash.push_back(nullptr);
}

int get(int key) {
    if(hash[(key)]!=nullptr)
    {
        int v = hash[key]->first;
        lru.erase(hash[key]);
        lru.push_front({v,key});
        hash[key] = lru.begin();
        return v;
    }
    else
        return -1;
}

void put(int key, int value) {
    if(hash[(key)]!=nullptr)
    {
        int v = value;
        lru.erase(hash[key]);
        lru.push_front({v,key});
        hash[key] = lru.begin();
    }
    else if(lru.size()<cap)
    {
        lru.push_front({value,key});
        hash[key] = lru.begin();
    }
    else
    {
        lru.push_front({value,key});
        hash[key] = lru.begin();
        auto it = lru.end();
        it--;
        hash[(it->second)] = nullptr;
        lru.erase(it);
    }
}
};

This way does not work either.

vector<list<pair<int, int>>::iterator> hash(3001,NULL);

Can we not create a vector of pointers?


Solution

  • Create an iterator variable, instead of nullptr value, as bellow:

    list<pair<int, int>>::iterator emptyIt;  // this iterator object refer to nothing
    
    // Using `emptyIt` to initialize the hash
    LRUCache(int capacity) {
        cap = capacity;
        for(int i=0;i<=3000;i++)
            hash.push_back(emptyIt);
    }
    
    // Using emptyIt instead of nullptr
    int get(int key) {
        if(hash[(key)]!=emptyIt)
        {
            int v = hash[key]->first;
            lru.erase(hash[key]);
            lru.push_front({v,key});
            hash[key] = lru.begin();
            return v;
        }
        else
            return -1;
    }
    
    void put(int key, int value) {
        if(hash[(key)]!=emptyIt)
        {
            int v = value;
            lru.erase(hash[key]);
            lru.push_front({v,key});
            hash[key] = lru.begin();
        }
        else if(lru.size()<cap)
        {
            lru.push_front({value,key});
            hash[key] = lru.begin();
        }
        else
        {
            lru.push_front({value,key});
            hash[key] = lru.begin();
            auto it = lru.end();
            it--;
            hash[(it->second)] = emptyIt;
            lru.erase(it);
        }
    }
    };