简体   繁体   English

std :: move into static_pointer_cast:为什么static_pointer_cast没有rvalue引用重载?

[英]std::move into static_pointer_cast: Why doesn't static_pointer_cast have an rvalue reference overload?

Suppose we have a fuction expecting a shared pointer by value. 假设我们有一个函数,期望按值共享指针。 (In a real life example I take it by rvalue reference and forward it to a member.) (在现实生活中的例子中,我通过右值引用将其转发给成员。)

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

But we only have a shared pointer to the base class, so we use static_pointer_cast : 但是我们只有一个指向基类的共享指针,所以我们使用static_pointer_cast

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

Does the first assignment (construction of ptr from the temporary) trigger an atomic increment and decrement of the reference count or is the shared pointer moved? 第一个赋值(从临时构造ptr)是触发引用计数的原子递增和递减还是共享指针移动? (Note that it's being up-casted.) (注意它正在升级。)

Within the static_pointer_cast there is an atomic increment of the reference count. static_pointer_cast中,引用计数的原子增量。 In case we don't need ptr anymore, we'd want to move it into f . 如果我们不再需要ptr ,我们想把它移到f But as there is no overload of static_pointer_cast taking an rvalue reference, the move won't have any effect: 但由于static_pointer_cast没有超载采用右值引用,因此移动不会产生任何影响:

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

We still have the atomic increment and the corresponding atomic decrement as soon as ptr is destructed. 一旦ptr被破坏,我们仍然有原子增量和相应的原子减量。 Why is there no such overload? 为什么没有这样的超负荷?

I can answer the first part of your question, but not the second. 我可以回答你问题的第一部分,但不是第二部分。 While I'm not sure whether it's mandated by the standard, I'm pretty sure that: 虽然我不确定它是否符合标准,但我很确定:

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

Will not do any extraneous refcounter increments/decrements. 不会做任何无关的refcounter增量/减量。 First, let me observe that this is actually not an assignment at all, but construction of ptr . 首先,让我观察一下,这实际上不是一项任务,而是ptr构建。 Clearly it's been constructed by a temporary, and clearly the temporary is of a different type. 显然,它是由一个临时构建的,显然临时属于不同类型。 The signature of the constructor that will be matched is ( http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr ): 将匹配的构造函数的签名是( http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr ):

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

In the notes it says: 在说明中它说:

Move-constructs a shared_ptr from r. 从r构造一个shared_ptr。 After the construction, *this contains a copy of the previous state of r, r is empty and its stored pointer is null. 在构造之后,*它包含r的先前状态的副本,r为空并且其存储的指针为空。 The template overload doesn't participate in overload resolution if Y* is not implicitly convertible to T* 如果Y *不可隐式转换为T *,则模板重载不参与重载解析

In this case, Y is Derived and T is Base , so clearly we get implicit conversion from Y* to T* , so the constructor is legal. 在这种情况下, YDerivedTBase ,所以很明显我们得到从Y*T*隐式转换,所以构造函数是合法的。 Strictly speaking it might be conforming to allow the reference count to first rise to 2, and then drop back down to 1. But obviously this defeats the whole purpose of a move constructor so I rather strongly doubt this is how it is implemented. 严格来说,它可能符合允许引用计数首先上升到2,然后降回到1.但显然这会破坏移动构造函数的整个目的,所以我强烈怀疑这是如何实现的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 `static_pointer_cast` 不能与 ADL 一起使用,但需要显式的 `std::`? - Why doesn't `static_pointer_cast` work with ADL, but requires explicit `std::`? 通过继承和模板进行static_pointer_cast - static_pointer_cast through inheritance and template static_pointer_cast是否更新引用计数 - Does static_pointer_cast update reference counting std :: static_pointer_cast是否有任何额外的运行时开销? - Does std::static_pointer_cast have any additional runtime overhead? 为什么 std::shared_ptr 在使用 std::static_pointer_cast 时会析构两次? - Why std::shared_ptr destruct twice when used std::static_pointer_cast? std :: static_pointer_cast vs static_cast <std :: shared_ptr <A >> - std::static_pointer_cast vs static_cast<std::shared_ptr<A>> unique_ptr的static_pointer_cast替代方案 - Alternatives of static_pointer_cast for unique_ptr static_pointer_cast 调用应该是 std:: 限定的,还是依赖于 ADL? - Should static_pointer_cast calls be std:: qualified, or relied upon ADL? 存储 std::weak_ptr<void> 并使用 static_pointer_cast - Storing of std::weak_ptr<void> and using static_pointer_cast 如何在 C++ 中不使用 std::static_pointer_cast 向下转换 shared_ptr? - How to downcast shared_ptr without std::static_pointer_cast in C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM