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

Define custom iterator that calls function to passed element

本文关键字:元素 自定义 迭代器 函数调用 定义      更新时间:2023-10-16

我经常编写如下代码(这里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) .

我认为你想要提升的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 * -> Derived * 转换时,这更有意义

您可以使用

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