我经常编写如下代码(这里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)
。
答案 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_if
和std::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); })
);