Reputation: 3396
Let's get the formalities out of the way.
17.3.28 valid but unspecified state [defns.valid]
an object state that is not specified except that the object's invariants are met and operations on the object behave as specified for its type
[ Example: If an object
x
of typestd::vector<int>
is in a valid but unspecified state,x.empty()
can be called unconditionally, andx.front()
can be called only ifx.empty()
returns false. — end example ]
Some users have suggested that std::move(x).something()
is nonsensical. But I'm having trouble understanding the difference between std::move(x).something()
and y = std::move(x); y.something()
. Observe:
// -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
std::vector<int> v;
v.pop_back();
// Error: attempt to access an element in an empty container.
Now we want to try our nonsensical case:
std::vector<int> v(10);
std::move(v).pop_back();
No error. This must be the "valid but unspecified" everyone's talking about, but let's keep going.
std::vector<int> v(10);
std::cout << std::move(v).size();
auto v2 = std::move(v);
std::cout << v.size();
This prints 100
. That's not too surprising. std::move
is just a cast, it doesn't actually perform the job of the move constructor.
Am I missing something or is std::move(x).something()
still non-sensical (other than being a no-op)?
For reference, see the comments on Member function .begin() and std::begin() as well as the upvoted answer.
The following example suggests that v
is not moved from:
template< class C >
auto begin( C&& c ) -> decltype(c.begin())
{
return c.begin();
}
int main()
{
std::vector<int> v(10);
std::vector<int>::iterator it3 = begin(std::move(v));
std::cout << v.size();
}
Outputs 10
.
Upvotes: 2
Views: 84
Reputation: 62583
std::move
doesn't do anything to the object! All it does is casting an object to an ravlue, so that it can be bound by rvalue reference.
Any modifications to the object are done by corresponding move constructor or move assingnment operator. If none are called, nothing happens at all.
Upvotes: 5
Reputation: 217275
But I'm having trouble understanding the difference between
std::move(x).something()
andy = std::move(x); y.something()
With (note the &
/&&
after const
)
struct S
{
void foo() const & {std::cout << "l-value this\n"; }
void foo() const && {std::cout << "r-value this\n"; }
};
You got:
S tmp;
std::move(tmp).foo(); // "r-value this
S x = std::move(tmp);
x.foo(); // "l-value this
Upvotes: 0