为什么在rvalue引用上使用std :: forward会导致被引用对象的破坏?

Vio*_*ffe 1 c++ rvalue-reference perfect-forwarding c++11

#include <functional>
#include <memory>
#include <iostream>

struct A
{
    ~A() {std::cout << "~A()" << std::endl;}
};

void test(std::shared_ptr<A> ptr)
{
    std::cout << (ptr ? "not empty" : "empty") << std::endl;
}

void forwarder(std::function<void(std::shared_ptr<A>)> f, std::shared_ptr<A>&& ptr)
{
    f(std::forward<std::shared_ptr<A>>(ptr));
    f(std::forward<std::shared_ptr<A>>(ptr));
}

void main()
{
    forwarder([](std::shared_ptr<A> ptr){ test(ptr); }, std::make_shared<A>());
}
Run Code Online (Sandbox Code Playgroud)

问题在于forwarder功能.在第一次调用后,testshared_ptr与一起-被破坏A的对象,很明显.所以在第二次调用test指针时已经是空的.我不明白为什么会这样.std::forward实施是微不足道的.
所以,我有两个问题:
1.如何std::forward导致rvalue对象的破坏传递给它?哪一段代码呢?
2.如何解释这个C++设计决策?似乎违反直觉的,我认为ptr超出范围还没有,但已经死了.

Pup*_*ppy 5

它没有被破坏,它被移走了.有一个很大的不同.你的使用std::forward也完全不正确,只是FTR.

在这种情况下,std::forward<T>相当于std::move,这意味着将ptr其移入函数中.移动就像复制操作,但保留源对象的状态.因此,不出所料,以后它是空的,因为它已被移走.

参数f是由我们调用它返回的rvalue构造的std::move(ptr).