I often see the following idiom in production code: A value argument (like a shared pointer) is handed into a constructor and shall be copied once. To ensure this, the argument is wrapped into a std::move application. Hating boilerplate code and formal noise I wondered if this is actually necessary. If I remove the application, at least gcc 7 outputs some different assembly.
#include <memory> class A { std::shared_ptr<int> p; public: A(std::shared_ptr<int> p) : p(std::move(p)) {} //here replace with p(p) int get() { return *p; } }; int f() { auto p = std::make_shared<int>(42); A a(p); return a.get(); } Compiler Explorer shows you the difference. While I am not certain what is the most efficient approach here, I wonder if there is an optimization that allows to treat p as a rvalue reference in that particular location? It certainly is a named entity, but that entity is "dead" after that location anyway.
Is it valid to treat a "dead" variable as a rvalue reference? If not, why?
shared_ptris a special case here ... its copy operation is to make another pointer to the same managed object. Are you intending specifically to ask about shared_ptr? This differs from most objects which do a complete copy of their state when copied.