Variables can be automatically moved when a function returns. However,
declaring a variable as const prevents that move from occuring (as the
move modifies the moved-from variable).
This checks when a move constructor for an object copy constructs its
member classes or parent classes. Copying unnecessary as all of the
members of the moved-from object can be clobbered by the move.
If a function takes in an rvalue, it's taking ownership of the object
that's being moved into it. If the object never moves that rvalue param,
then there was no point to moving it into the function.
As an example of a problem this catches, in context_manager.cpp,
replace_map_context_with took in an rvalue unique_ptr "mc" to a map
context. The function then swapped it with a given value in
map_contexts_. This swap was unnecessary because "mc" expired after the
function call was complete. It is more optimal to std::move(mc) into
the value in map_context_ that we were previously swapping with.
A forwarding reference is one of the form (note the template parameter):
template<class X>
void foo( X&& x );
The difference between this and a regular rvalue reference (where X is
not a template) is that foo() also accept lvalues. So it is possible to
call:
std::string s = "Example";
foo(s)
And if the body of foo(X&& x) std::moves x, then s will be invalidated.
This check warns on usage of std::move in this context and recommends
std::forward, which automatically determines whether to std::move
depending on whether foo() is called with an rvalue or an lvalue.