Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

std::unordered_map using a template class pointer as a key

I’m a beginner for cpp,and I have some codes like this:

#include <iostream>
#include <utility>
#include <map>
#include <unordered_map>


template<typename T,typename EX>
class Attachable
{
    
    static std::unordered_map<T*,Attachable<T,EX>> attachCaches;

    std::unordered_map<std::string,EX> datas;

    Attachable(T* sender):m_attachedObj(sender)
    {
    }

    bool operator==(const Attachable& other)const
    {
        return m_attachedObj == other.m_attachedObj;
    }
public:

    static Attachable<T,EX> attach(T* sender)
    {
        if(attachCaches.find(sender)==attachCaches.end())
        {
            attachCaches.insert(std::make_pair((sender),Attachable<T,EX>(sender)));
        }

        return attachCaches[(sender)];
    }


    void set(std::string key,EX properties)
    {
        datas.insert(key,properties);
    }

    EX get(std::string key)
    {
        return datas.at(key);
    }

private:
    T* m_attachedObj;
};


class Tester
{
public :
    Tester(){}
};

int main()
{
    Tester* a =new Tester();

    Attachable<Tester,std::string>::attach(a).set("test","typeOfInt");

    std::cout<< Attachable<Tester,std::string>::attach(a).get("test");

}

**When I try to compile this code , I will receive an error at ,line 952,at the function called

emplace(*_First);

**

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

    template <class _Iter, class _Sent>
    void _Insert_range_unchecked(_Iter _First, const _Sent _Last) {
        for (; _First != _Last; ++_First) {
            emplace(*_First);
        }
    }

I am trying to using some basic pointer like int,but this still not worked:

int* a =new int(4);

    Attachable<int,std::string>::attach(a).set("test","typeOfInt");

    std::cout<< Attachable<int,std::string>::attach(a).get("test");

>Solution :

attachCaches[(sender)] may need to default-construct an Attachabe object, if it turns out that sender is not in the map. But Attachable doesn’t provide a default constructor. Since you actually know the key is always in the map, you can implement attach this way (also more efficient, as it eliminates redundant lookups):

static Attachable<T,EX>& attach(T* sender)
{
    auto it = attachCaches.find(sender);
    if (it == attachCaches.end())
    {
        it = attachCaches.emplace(sender, Attachable<T,EX>(sender)).first;
    }

    return it->second;
}

Note also how the function now returns Attachable by reference. Your original code returned a temporary copy of the map element; then called set on that copy; then that copy was destroyed. The original in the map was never updated, so a subsequent get didn’t find the value passed to set.

Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading