For regular local const reference variables, the scope is prolonged. Which is why the following code works as expected:
#include <iostream>
#include <memory>
struct foo
{
foo()
{
std::cout << "foo() @" << (void*)this << std::endl;
}
~foo()
{
std::cout << "~foo() @" << (void*)this << std::endl;
}
};
int main()
{
auto const& f = std::make_shared<foo>();
std::cout << "f = " << f.get() << std::endl;
return 0;
}
// prints:
// foo() @0x55f249c58e80
// f = 0x55f249c58e80
// ~foo() @0x55f249c58e80
It seems though that this does not work as expected when assigning a moved object using std::move()
:
#include <iostream>
#include <memory>
#include <list>
struct foo
{
foo()
{
std::cout << "foo() @" << (void*)this << std::endl;
}
~foo()
{
std::cout << "~foo() @" << (void*)this << std::endl;
}
};
int main()
{
std::list<std::shared_ptr<foo>> l;
l.push_back(std::make_shared<foo>());
auto const& f = std::move(l.front());
l.clear();
std::cout << "f = " << f.get() << std::endl;
return 0;
}
// prints
// foo() @0x564edb58fe80
// ~foo() @0x564edb58fe80
// f = 0x564edb58fe80
Does std::move()
indeed change the scope, or am I dealing with a compiler bug?
Changing the variable from auto const& f
to just auto f
fixes the problem. If I wrap the move into another function, it also works:
auto const& f = [&]() { return std::move(l.front()); }();
It's almost like std::move()
does not share the same semantics as a function call, but rather as if it was just a regular variable assignment:
auto const& f = std::move(l.front());