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);
**
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
.