'Get first N elements of std::list?

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



Solution 1:[1]

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

Solution 2:[2]

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

Solution 3:[3]

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

Solution 4:[4]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ecatmur
Solution 3 timrau
Solution 4 Pavan Chandaka