我有一个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_if
和std::transform
之间交叉的算法。有这样的野兽吗?
答案 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));