In addition to what others have said:
std::move is actually just a static_cast that converts an lvalue to an rvalue/rvalue reference.
It does nothing to something that's already an rvalue, like it's used in your first example.
The second example is a pretty typical use of std move. crap is a named variable and therefore an lvalue, but my using std::move, you're indicating that the variable is not intended to be used anymore except to destroy it, so it's ok to move the guts out of it. So std::move casts the type to an rvalue reference.
But because Crap doesn't have a non-trivial move constructor, using std::move has no effect anyway. Also note, stl containers will not call move constructors that aren't marked as noexcept, when doing so would prevent the strong exception guarantee.
I'm still learning C++ myself so somebody correct me if I'm wrong, but my understanding is the move constructors (and move assignment operators) are for objects that manage memory or other resources. For example, if I had an object that held a gigabyte-sized array of data then the copy constructor would need to *copy* that huge chunk of RAM which is pretty wasteful if the argument is a temporary that's just going to be destroyed as soon as it goes out of scope. The move constructor knows that its argument is temporary so it can simply take over responsibility for freeing that chunk of RAM instead of copying it.
Put another way, it's not the object that's moving but rather it's the responsibility for the resources it contains that is being handed off from one object to another.
Do I have that right?
Yeah, that's correct.