英文:
std::unordered_map using a template class pointer as a key
问题
我是cpp的初学者,我有一些类似这样的代码:
```cpp
#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");
}
当我尝试编译这段代码时,我会在emplace(*_First);
的函数处:
template <class _Iter, class _Sent>
void _Insert_range_unchecked(_Iter _First, const _Sent _Last) {
for (; _First != _Last; ++_First) {
emplace(*_First);
}
}
我尝试使用一些基本的指针,比如int,但仍然不起作用:
int* a = new int(4);
Attachable<int,std::string>::attach(a).set("test","typeOfInt");
std::cout<< Attachable<int,std::string>::attach(a).get("test");
<details>
<summary>英文:</summary>
**I'm a beginner for cpp,and I have some codes like this:**
```cpp
#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 <xhash>,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");
答案1
得分: 3
attachCaches[(sender)]
可能需要默认构造一个 Attachable
对象,如果发现 sender
不在映射中。但是 Attachable
并没有提供默认构造函数。由于您实际上知道键始终在映射中,您可以这样实现 attach
(也更有效,因为它消除了冗余的查找):
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;
}
请注意,函数现在通过引用返回 Attachable
。您的原始代码返回映射元素的临时副本;然后在该副本上调用 set
;然后销毁了该副本。映射中的原始值从未更新,因此随后的 get
没有找到传递给 set
的值。
英文:
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论