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

时间:2018-09-06 06:21:27

标签: c++ stl-algorithm

我有一个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之间交叉的算法。有这样的野兽吗?

1 个答案:

答案 0 :(得分: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; });

另一种可能性是使用范围库,因为它们的主要目的之一是易于组合算法。提升范围:

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