【发布时间】:2014-01-30 15:30:01
【问题描述】:
我一直在使用unordered_map<int, myObject> 和myObject* 指向无序映射中对象的指针。这已经工作了一段时间,但我最近发现我错误地认为添加到无序映射的 myObject 的内存位置将始终保持不变。
在无序映射中添加和删除元素时,我可以通过使用unordered_map<int, myObject*> 和new 和delete 来解决问题。
由于我有相当多的代码,我不想在代码中修改无序映射的每个地方都添加new 和delete,我宁愿尝试重载unordered_map::operator[] 和unordered_map::erase() 这样new 和 delete 的使用将透明地发生,我不必更改现有代码。 unordered_map::operator[] 然后可以返回对 myObject 本身的引用而不是指针。
我尝试过继承unordered_map,但我不确定应该如何添加模板参数列表:
using namespace std;
template<class _Kty,
class _Ty,
class _Hasher = hash<_Kty>,
class _Keyeq = equal_to<_Kty>,
class _Alloc = allocator<pair<const _Kty, _Ty> > >
class my_unordered_map : public unordered_map<_Umap_traits<_Kty, _Ty,
_Uhash_compare<_Kty, _Hasher, _Keyeq>, _Alloc, false> >
{
};
但我收到以下错误:
error C2976: 'std::unordered_map' : too few template arguments
error C2955: 'std::unordered_map' : use of class template requires template argument list
然后我意识到,当使用带有unordered_map 的myObject* 类型时,可以向std 添加一个特化,但我不确定是否甚至可以用特化重载operator[]。
感谢您的帮助!
编辑:
我现在创建了一个template <class mapped_type> 类,其中unordered_map<int, mapped_type*> 作为内部结构。 operator[] 包含相当简单:
template <class mapped_type> class MyMap {
public:
std::unordered_map<int, mapped_type*> internal_map;
mapped_type& operator[](int&& _Keyval)
{ // find element matching _Keyval or insert with default mapped
mapped_type*& ptr = internal_map[_Keyval];
if (ptr == nullptr) ptr = new mapped_type();
return *ptr;
}
}
void erase(const int& _Keyval)
{ // erase and count all that match _Keyval
mapped_type* ptr = internal_map[_Keyval];
if (ptr) delete ptr;
internal_map.erase(_Keyval);
}
void clear()
{ // erase all
internal_map.clear();
}
现在问题是擦除方法(默认方法包含在std::_Hash 中)。我真的不需要迭代器,所以我想最好的方法可能是首先使用operator[] 方法来查找条目,然后在将其从internal_map 中删除之前使用delete,或者您还有其他想法吗?可能更合适?
编辑:添加了擦除建议。这有道理吧?
【问题讨论】:
-
使用
myObject的值语义包装器怎么样?类似于unique_ptr<myObject>,但在默认ctor 中自动创建myObject。或者您可以使用std::map,它的insert函数不会使引用无效。 -
感谢您的评论,我不知道
std::map并没有使引用无效。我现在已经更新了我的问题,我将首先尝试以建议的方式解决它。 -
您正在更改地图中存储的指针的副本。你必须使用类似
mapped_type*& ptr = internal_map[_Keyval]; -
确实如此,谢谢! :)
-
“我最近发现我错误地认为添加到无序映射中的 myObject 的内存位置将始终保持不变。”你是对的,现在又错了:修改
unordered_map的操作可以使迭代器 无效,但不能使指针或对元素的引用无效(擦除元素的明显例外)。元素本身永远不会移动。
标签: c++ operator-overloading template-specialization unordered-map