gpt4 book ai didi

c++ - std::move into static_pointer_cast:为什么 static_pointer_cast 没有右值引用重载?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:39:41 26 4
gpt4 key购买 nike

假设我们有一个函数需要一个按值共享的指针。 (在现实生活中的例子中,我通过右值引用获取它并将其转发给成员。)

void f(std::shared_ptr<Derived> ptr) { ... }

但是我们只有一个指向基类的共享指针,所以我们使用static_pointer_cast:

std::shared_ptr<Base> ptr = std::make_shared<Derived>();
f(std::static_pointer_cast<Derived>(ptr));

第一个赋值(从临时构造 ptr)是否触发了引用计数的原子递增和递减,或者共享指针是否被移动? (请注意,它正在向上转换。)

static_pointer_cast 中有引用计数的原子增量。如果我们不再需要 ptr,我们想将它移到 f 中。但是由于没有重载 static_pointer_cast 获取右值引用,因此移动不会有任何效果:

f(std::static_pointer_cast<Derived>(std::move(ptr)));

一旦ptr 被破坏,我们仍然有原子增量和相应的原子减量。为什么没有这种重载?

最佳答案

我可以回答你问题的第一部分,但不能回答第二部分。虽然我不确定它是否是标准强制要求的,但我很确定:

std::shared_ptr<Base> ptr = std::make_shared<Derived>();

不会做任何无关的引用计数器递增/递减。首先,让我观察一下,这实际上根本不是赋值,而是 ptr 的构造。很明显它是由临时工 build 的,而且显然临时工是不同类型的。将匹配的构造函数的签名是 ( http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr ):

template< class Y > 
shared_ptr( shared_ptr<Y>&& r );

在注释中说:

Move-constructs a shared_ptr from r. After the construction, *this contains a copy of the previous state of r, r is empty and its stored pointer is null. The template overload doesn't participate in overload resolution if Y* is not implicitly convertible to T*

在这种情况下,YDerivedTBase,所以很明显我们从Y*T*,所以构造函数是合法的。严格来说,允许引用计数先上升到 2,然后回落到 1 可能是合规的。但显然这违背了移动构造函数的全部目的,所以我非常怀疑它是如何实现的。

关于c++ - std::move into static_pointer_cast:为什么 static_pointer_cast 没有右值引用重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43771128/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com