【发布时间】:2013-09-27 04:56:46
【问题描述】:
我经常发现自己想写这样的代码:
class MyClass
{
public:
void addObject(std::unique_ptr<Object>&& newObject);
void removeObject(const Object* target);
private:
std::set<std::unique_ptr<Object>> objects;
};
然而,std::set 接口的大部分内容对于 std::unique_ptrs 来说是无用的,因为查找函数需要 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 的原始指针映射。
// ... std::map<const Object*, std::unique_ptr<Object>> objects; };
但是,在我看来,两者都有些愚蠢。在解决方案 1 中,erase() 不是 noexcept,因此临时的 unique_ptr 可能会删除它并不真正拥有的对象,并且 2 不必要地需要双倍的容器存储空间。
我知道 Boost 的指针容器,但与现代 C++11 标准库容器相比,它们当前的功能有限。
我最近在阅读有关 C++14 的内容,遇到了“向关联容器添加异构比较查找”。但是根据我的理解,查找类型必须与键类型相当,但原始指针不能与 unique_ptrs 相比。
有谁知道解决这个问题的更优雅的解决方案或即将加入的 C++ 解决方案?
【问题讨论】:
-
有趣,这看起来像是容器类中的设计疏忽——应该有一种简单的方法来做到这一点。
-
同意。也许应该有类似于 Yakk 的 pointer_comp 的
std::ptr_less、std::ptr_equal_to、std::ptr_hash等,以简化指针比较/查找。它们与 C++1y 对关联容器的异构比较查找配合得很好。 -
离题:您不应该通过右值引用获取唯一指针;仅按价值就足够了。
标签: c++ c++11 unique-ptr c++14