Reputation: 65951
What is the correct and safe way to get a new list that is the first N elements of a std::list or the entire list if N >= the list size (and handles N = 0 as well)?
Update
In fact I don't necessarily need a new list, I just want to operate on the subset of the list in subsequent code. I assume creating a new list is a reasonable way to do this (note list size will typically be under 50).
Upvotes: 3
Views: 8042
Reputation: 12751
In your question noticed saying
In fact I don't necessarily need a new list, I just want to operate on the subset of the list in subsequent code
Form C++17 one can use std::for_each_n
For example lets square the first N (4) numbers in the list.
Example 1 : Modify in place :
std::list<int> nums{ 1,2,3,4,5,6,7,8 };
//MAKE NOTE OF SENDING ARGUMENT AS A REFERENCE (int& num)
std::for_each_n(nums.begin(), 4, [](int& num) { num = num * num; });
//PRINT
for (auto n : nums)
std::cout << n << " ";
Example 2 : Modify and put them in a different list :
std::list<int> nums2{ 1,2,3,4,5,6,7,8 };
std::list<int> newNums;
//MAKE NOTE OF CAPTURE [&}, newNums EXPOSED INSIDE LAMBDA.
std::for_each_n(nums2.begin(), 4, [&](int num) {newNums.push_back(num * num); });
//PRINT
for (auto n : newNums)
std::cout << n << " ";
Also there is an overload available to specify execution policy, Need to include "execution" header. So the below code executes with parallel execution policy, useful for parallel processing lists huge in size.
std::for_each_n(std::execution::par,nums.begin(), 4, [](int& num) { num = num * num; });
Upvotes: 0
Reputation: 28178
std::list<int> a;
size_t n = 13;
auto end = std::next(a.begin(), std::min(n, a.size()));
Make a new list containing the first n elements of the first list:
std::list<int> b(a.begin(), end);
Or populate an existing list:
std::list<int> b;
std::copy(a.begin(), end, std::back_inserter(b));
Upvotes: 9
Reputation: 157344
template<typename T>
std::list<T> first_n(const std::list<T> &in, std::size_t n) {
return std::list<T> out{in.begin(),
std::next(in.begin(), std::min(in.size(), n))};
}
Upvotes: 6
Reputation: 23058
// list<int> input;
list<int> output;
for (list<int>::const_iterator i = input.begin(); i != input.end() && N > 0; ++i, --N)
output.push_back(*i);
Upvotes: 4