We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Copy, Move, and the Rule of Zero step 2 of 5
When std::move selects a copy
std::move(x) does not transfer resources by itself. It casts the expression
to an rvalue reference, allowing a receiving operation to select a move
overload. A constructor or assignment operator performs the actual transfer.
For the Payload type provided below:
Payload source;
Payload destination = std::move(source); // calls Payload(Payload&&)
Payload contains a vector. Its move constructor moves that member instead
of copying the vector's elements. Other types define their own move behaviour;
a move does not universally mean "empty the source".
Why a call to std::move can still copy
The starter uses a const reference to each payload:
const Payload& part = parts[0];
out.push_back(std::move(part));
std::move preserves const, so this expression has type const Payload&&.
The provided move constructor takes Payload&& and cannot accept it.
The copy constructor takes const Payload&, so it can be used instead.
With a mutable reference, the move overload becomes available:
Payload& part = parts[0];
out.push_back(std::move(part));
This rule concerns the overloads available for this type. A type can declare
other constructors, including one taking const T&&; the usual resource-
transferring move takes T&& because it needs to modify the source.
Two other cases are worth recognizing:
- A function taking only
const Payload&still receives a reference when called withstd::move(payload). Passing that reference does not copy or move the payload; what the function does inside determines any transfer. - If no move constructor is declared, a compatible copy constructor may be
used. This differs from explicitly declaring
T(T&&) = delete: if that deleted overload is selected, construction fails to compile.
Returning the result
Use return out; for this function's local vector. The compiler can construct
it directly as the result, avoiding a move through named return value
optimization (NRVO). If NRVO is not applied here, the vector can be moved.
Writing return std::move(out); prevents NRVO for that return expression.
Your task
std::vector<Payload> take(std::vector<Payload>& parts, int limit);
Move the first limit payloads into a new vector, preserving their order.
Take all payloads if limit exceeds the size, and none if limit <= 0.
Keep the size of parts unchanged and leave unselected elements untouched.
Input sizes fit in int for this exercise.
For payload data [[1, 2], [3], [4]] and limit = 2, the returned vector
contains [[1, 2], [3]], and parts still has three elements. Do not rely
on the previous contents of an element after moving from it.
Leave Payload unchanged. Its copy counter must remain zero during take.
The harness reports the returned data, the copy count and the remaining size
of parts. Clang-tidy's performance-move-const-arg check can also identify
the const reference that causes the starter to copy.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
C++ reference solution
Sign in to track your attempts toward unlocking the reference solution.