Question

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).

Was it helpful?

Solution

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));

OTHER TIPS

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))};
}
// 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);

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; });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top