我经常发现自己想要编写这样的代码:
class MyClass
{
public:
void addObject(std::unique_ptr<Object>&& newObject);
void removeObject(const Object* target);
private:
std::set<std::unique_ptr<Object>> objects;
};
然而,对于使用std::unique_ptrs的情况,std::set接口的大部分功能都有些无用,因为查找函数需要std::unique_ptr参数(我显然没有它们,因为它们由集合本身拥有)。
我可以想到两种主要解决方案。
为查找创建一个临时的unique_ptr。例如,上面的removeObject()可以这样实现:
void MyClass::removeObject(const Object* target)
{
std::unique_ptr<Object> targetSmartPtr(target);
objects.erase(targetSmartPtr);
targetSmartPtr.release();
}
用指向unique_ptrs的原始指针的map替换集合。
// ...
std::map<const Object*, std::unique_ptr<Object>> objects;
};
然而,对我来说两种解决方案都有些愚蠢。在第一种解决方案中,erase()不是noexcept的,因此临时unique_ptr可能会删除它实际上并未拥有的对象,2需要不必要地为容器提供双倍的存储空间。
我知道Boost的指针容器,但它们当前的功能与现代C++11标准库容器相比有限。
最近我在阅读C++14,发现了“向关联容器添加异构比较查找”。但从我的理解上看,查找类型必须可以与键类型进行比较,但裸指针不能与unique_ptrs进行比较。
是否有人知道更优雅的解决方案或即将添加到C++的解决此问题的新功能?
std::ptr_less
、std::ptr_equal_to
、std::ptr_hash
等,来简化指针比较和查找。它们将与C++1y的异构比较查找相结合,使关联容器更加方便。 - jbatez