定义调用函数以传递元素的自定义迭代器

时间:2018-01-24 17:00:50

标签: c++ c++11

我经常编写如下代码(这里int和double只是示例,类型通常是指针)

std::vector<int> va {1 ,2, 3};
std::vector<double> vb;

bool valid(int i) { return i % 2 == 0;}

for(auto a : va)
   if (valid(a))
      vb.push_back(static_cast<double>(a));

因为我们没有transform_if我想通过定义一些特殊的迭代器来知道是否有办法做到这一点:

template<typename T>
struct inserterStaticCast
{
    // not sure what to put here...
}

然后我可以编写像

这样的代码
std::vector<double> vc(a.size());
std::copy_if(a.begin(), a.end(), inserterStaticCast<double>(vc), &valid);

我也会对backInserterStaticCast版本感兴趣。

这在C ++ 11中是否可行?

谢谢

一些澄清......

我不能使用提升。再次在这种情况下int和double只是为了说明,在一般情况下我需要一个演员,通常是类似的 static_cast<derived *>(base_ptr)

2 个答案:

答案 0 :(得分:3)

我认为你想要提升function_output_iterator。在你的例子中,它将是

auto cast_back_iterator = make_function_output_iterator([&b](int i){ b.push_back(static_cast<double>(i)); });
std::copy_if(a.begin(), a.end(), cast_back_iterator, valid);

当两种类型之间没有隐式转换时更有意义,例如使用Base * - &gt; Derived *转化

答案 1 :(得分:1)

您可以使用std::copy_ifstd::back_inserter进行过滤:

std::vector<double> vc;
std::copy_if(va.begin(), va.end(), std::back_inserter(vc), valid);

或使用boost::range::adaptors::filtered(与您的问题相同的问题):

#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp>

#include <vector>

bool valid(int i) { return i % 2 == 0;}

int main() {
    std::vector<int> va {1 ,2, 3};

    using namespace boost::adaptors;
    auto vb = boost::copy_range<std::vector<double>>(va | filtered(valid));
}

请注意,将int转换为double是隐式的,不需要转换。

如果您确实需要转化,只需投入transformed

auto vb = boost::copy_range<std::vector<double>>(va
    | filtered(valid)
    | transformed([](int a) { return static_cast<double>(a); })
    );