弱指针使用的 static_pointer_cast

19

在C++0x中,std::shared_ptr有一个std::static_pointer_cast方法,但是std::weak_ptr没有类似的方法。这是有意为之,还是一个疏忽呢?如果是疏忽,我该如何定义一个合适的函数呢?

3个回答

14
这应该对你有所帮助:

这应该能解决你的问题:

template<class T, class U>
std::weak_ptr<T>
static_pointer_cast(std::weak_ptr<U> const& r)
{
    return std::static_pointer_cast<T>(std::shared_ptr<U>(r));
}

如果weak_ptr已经过期,这将抛出一个异常。如果你想得到一个空的weak_ptr,则应该使用r.lock()代替。

1
你对这个有了解吗?考虑到这个写起来非常简单,我想知道为什么标准委员会没有把它包含进去。 - tgoodhart
2
我刚才浏览了标准文档,我觉得好像没有人提出过这个问题。我也找不到有关boost(std::weak_ptr的原始来源)中是否要求或建议它的记录。也许原因是编写它很简单,但选择正确的策略(抛出异常或空值)却不容易。而且提供两个函数(每个策略一个)并不是最佳选择,因为static_pointer_cast旨在成为通用名称,在指针类型是通用的代码中使用。 - Howard Hinnant

6
霍华德的版本是正确的,但在许多情况下,将 weakptr.lock() 直接传递给 std::static_pointer_cast 作为参数更加合理。
std::weak_ptr<A> a = ...;  
std::weak_ptr<B> b = std::static_pointer_cast<B>(a.lock());

这种语法明确地显示了正在发生的事情,并使代码易于阅读。


1
这里似乎有一个 bug。由于 a.lock() 是一个临时对象,当代码在使用 b 时,底层指针可能已被删除。实际上,再次阅读 static_pointer_cast 文档后,我错了。它返回一个共享指针,将与 a 的底层共享指针共享。 - John Gordon
这段代码可以工作,但它涉及到昂贵的运行时原子操作,而 static_pointer_cast 则始终是一个免费操作。 - aberaud

3
这里有意省略了一些内容,因为尽管它的名字中带有“指针”,但std::weak_ptr并不是指针类型,也不提供指针接口(如operator ->、operator *、static_pointer_cast等)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接