We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Copy, Move, and the Rule of Zero step 1 of 5
Read payloads without copying their contents
A declaration can create an independent copy even when the code only needs to read an existing object. In this exercise, Payload contains a vector of integers, so copying a Payload also copies that vector's contents.
The starter does this in two places:
for (Payload item : items) {
std::vector<int> data = item.data;
// Read data.
}
Each iteration constructs a Payload from an element of items. It then copies the copied Payload's data member into another vector. These are unnecessary here because the function never needs to modify or retain either copy.
Borrow the objects you only read
Bind references instead:
for (const Payload& item : items) {
const std::vector<int>& data = item.data;
// Read the original data through a const reference.
}
The references name existing objects; they do not duplicate the Payload or its vector. The caller's items and their contents must remain alive while those references are used. This function uses them only during the call.
Copying is not inherently wrong. A copy can provide an independent snapshot, and copying a small value such as int is often appropriate. The cost depends on the type: a vector copy duplicates its elements, whereas copying a pointer copies its address, not the object it points to. Avoid assuming every copy allocates or has a fixed byte cost.
A by-value parameter also does not always copy its caller's object:
void handle(std::string name);
Passing an existing string lvalue copies it, passing a suitable rvalue can move it, and a temporary may construct the parameter directly. Choose value or reference parameters according to ownership and lifetime needs.
Your task
Implement:
std::vector<int> heads(const std::vector<Payload>& items);
Return the first integer from each non-empty Payload, in input order. Skip
empty payloads and leave all input data unchanged. For [[1, 2], [], [-3], [0, 4]],
return [1, -3, 0]. Empty input or input containing only empty payloads returns
an empty vector. Repeated values remain repeated.
Keep Payload and its instrumentation unchanged. Avoid both copying Payload objects and making temporary copies of their data vectors just to read them. Check empty() before front() or index 0; neither operation is valid on an empty vector in this C++20 exercise.
What the copy counter measures
The harness resets Payload::copies after building the inputs and reports
[heads, copies]. For the worked example, expect [[1, -3, 0], 0].
The counter increments in Payload's copy constructor and copy assignment operator. In the starter, it records one Payload copy per input item, including empty payloads. The separate copy of item.data does not increment this counter, because it is a vector copy rather than a Payload copy.
A zero counter therefore does not prove that no copying or allocation occurred. The result vector still stores copies of the selected integers and may allocate memory. The goal is to avoid duplicating the input payloads and their vectors.
Clang-tidy checks such as performance-for-range-copy and performance-unnecessary-copy-initialization can identify unnecessary copies. Treat their diagnostics as guidance about specific declarations, not a complete measurement of runtime cost.
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.