如何从一个容器中取出某些元素并将其转换为另一个容器?

问题描述 投票:2回答:1

我有一个vector<int*>,我想把所有尖头的元素放入vector<int>。所有未指向的元素都设置为nullptr

我在考虑做这样的事情:

vector<int> copy_valid_elements(vector<int*> piv)
{
 vector<int> result;
 result.reserve(piv.size());
 auto end_it = std::remove_if(piv.begin(), piv.end(), [](int* p) { return !p; });
 std::transform(piv.begin(), end_it, back_inserter(result), [](int* p) { return *p; });
 return result;
}

但这需要不必要地移动阵列中的元素。我可以做一个for循环,但我希望有一个算法是std::copy_ifstd::transform之间的交叉。有这样的野兽吗?

c++ stl-algorithm
1个回答
6
投票

这是一个应用可选转换的函数模板,带有两个谓词:一个用于过滤,一个用于实际映射。

template <class InpIt, class OutIt, class Pred, class Fct>
OutIt transform_if(InpIt first, InpIt last, OutIt dest, Pred pred, Fct transform)
{
   while (first != last) {
      if (pred(*first))
         *dest++ = transform(*first);

      ++first;
   }

   return dest;
}

你可以这样称呼它

int n1 = 1, n2 = 2, n3 = 3;

std::vector<int*> input{&n1, nullptr, nullptr, nullptr, &n2, &n3, nullptr};
std::vector<int> result;

transform_if(input.cbegin(), input.cend(), std::back_inserter(result),
    [](auto *i){ return i != nullptr; }, [](auto *i){ return *i; });

另一种可能性是使用范围库,因为它们的主要目的之一是简单的算法组合。随着Boost范围:

#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

using namespace boost::adaptors;

/* Variable setup as above... */

boost::copy(input | filtered([](auto *i){ return i != nullptr; }) | indirected,
    std::back_inserter(result));
© www.soinside.com 2019 - 2024. All rights reserved.