获取std::list的前N个元素

Get first N elements of std::list?

本文关键字:元素 list std 获取 的前      更新时间:2023-10-16

获得std::list的前N个元素的新列表或如果N>=列表大小(并处理N = 0)的整个列表的正确和安全的方法是什么?

实际上我不一定需要一个新的列表,我只是想在后续代码中操作列表的子集。我认为创建一个新列表是一种合理的方法(注意列表大小通常小于50)。

std::list<int> a;
size_t n = 13;
auto end = std::next(a.begin(), std::min(n, a.size()));

创建一个包含第一个列表的前n个元素的新列表:

std::list<int> b(a.begin(), end);

或者填充现有列表:

std::list<int> b;
std::copy(a.begin(), end, std::back_inserter(b));
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);

在你的问题中注意到

实际上我并不需要一个新的列表,我只是想对它进行操作后续代码

中列表的子集

在c++ 17中可以使用std::for_each_n

例如,我们将列表中的前N(4)个数字平方。

例1:就地修改:

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

示例2:修改并将它们放在不同的列表中:

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

还有一个重载可用于指定执行策略,需要包含"execution"头。所以下面的代码以并行执行策略执行,对于并行处理大列表非常有用。

std::for_each_n(std::execution::par,nums.begin(), 4, [](int& num) { num = num * num; });