从列表中删除 boost::shared_ptr 的正确方法是什么?
我有一个 boost::shared_ptr
的 std::list
,我想从中删除一个项目,但我只有一个匹配的 T* 类型的指针列表中的项目之一。
但是我猜测我无法使用 myList.remove( tPtr ) 因为shared_ptr 没有为其模板参数类型实现 ==
。
我立即想到的是尝试 myList.remove(shared_ptr
,它在语法上是正确的,但它会因双重删除而崩溃,因为临时 shared_ptr
有一个单独的 use_count。
std::list< boost::shared_ptr<T> > myList;
T* tThisPtr = new T(); // This is wrong; only done for example code.
// stand-in for actual code in T using
// T's actual "this" pointer from within T
{
boost::shared_ptr<T> toAdd( tThisPtr ); // typically would be new T()
myList.push_back( toAdd );
}
{
//T has pointer to myList so that upon a certain action,
// it will remove itself romt the list
//myList.remove( tThisPtr); //doesn't compile
myList.remove( boost::shared_ptr<T>(tThisPtr) ); // compiles, but causes
// double delete
}
我看到剩下的唯一选择是使用 std::find 进行自定义比较,或者循环遍历列表并自己找到它,但似乎应该有更好的方法。
我是否遗漏了一些明显的东西,或者这是否太不标准,无法以干净/正常的方式进行删除?
I have a std::list
of boost::shared_ptr<T>
and I want to remove an item from it but I only have a pointer of type T* which matches one of the items in the list.
However I cant use myList.remove( tPtr )
I'm guessing because shared_ptr does not implement ==
for its template argument type.
My immediate thought was to try myList.remove( shared_ptr<T>(tPtr) )
which is syntactically correct but it will crash from a double delete since the temporary shared_ptr
has a separate use_count.
std::list< boost::shared_ptr<T> > myList;
T* tThisPtr = new T(); // This is wrong; only done for example code.
// stand-in for actual code in T using
// T's actual "this" pointer from within T
{
boost::shared_ptr<T> toAdd( tThisPtr ); // typically would be new T()
myList.push_back( toAdd );
}
{
//T has pointer to myList so that upon a certain action,
// it will remove itself romt the list
//myList.remove( tThisPtr); //doesn't compile
myList.remove( boost::shared_ptr<T>(tThisPtr) ); // compiles, but causes
// double delete
}
The only options I see remaining are to use std::find with a custom compare, or to loop through the list brute force and find it myself, but it seems there should be a better way.
Am I missing something obvious, or is this just too non-standard a use to be doing a remove the clean/normal way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你是对的,我们不能直接比较指针。但确实存在
remove_if
,我们可以指定自己的谓词。解决方案:只需将上述谓词保留在标头中的某个位置,您就可以在任何您想要的地方使用它。
最好的解决方案是从一开始就永远不要失去对
shared_ptr
的控制,因此我们可以只使用remove
,但以上方法无论如何都是无害的。You're correct, we can't directly compare the pointers. But there does exist
remove_if
, and we can specify our own predicate. The solution:Just keep the above predicate in a header somewhere, and you can use it wherever you want.
The best solution is to never lose hold of the
shared_ptr
in the first place, so we can just useremove
, but the above is harmless anyway.std::list 的 remove_if 成员就是您所需要的:
定义一个谓词
然后 您可以调用
列表来清理具有shared_ptrs到tThisPtr的节点。
(未经测试,所以也许一些语法问题需要修复)。
Michael Burr关于enable_shared_from_this的建议很好;最好完全避免使用原始 tThisPtr。
std::list's remove_if member is what you need:
Define a predicate
then you can call
to have the list clean up nodes which have shared_ptrs to tThisPtr.
(Untested, so maybe some syntactic stuff needs fixing).
Michael Burr's advice re enable_shared_from_this is good though; it'd be better to avoid having the raw tThisPtr in play at all.
enable_shared_from_this
可以帮助解决您的问题,但它需要您在列表中使用的类型派生自它:如果类型启用功能,您可以通过调用
shared_from_this()
从对象本身获取共享指针。enable_shared_from_this
can help with your problem, but it will require that the types you're using in the list derive from it:If the type enables that functionality, you can get the shared pointer from the object itself by calling
shared_from_this()
.可以使用共享指针来删除它吗?
Can you use the shared pointer to remove it?