lundi 29 décembre 2014

Why does using std::forward on an rvalue reference cause destruction of the object being referenced?


#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>());
}


The problem is in the forwarder function. After the first call to test the shared_ptr is destructed - along with the A object, obviously. So in the second call to test the pointer is already empty. I don't understand why that happens. std::forward implementation is trivial.

So, I have 2 questions:

1. How does std::forward cause the destruction of the rvalue object being passed to it? Which bit of code does that?

2. How can this C++ design decision be explained? Seems counter-intuitive to me that ptr is not out of scope yet but is already dead.


Aucun commentaire:

Enregistrer un commentaire