[英]Define custom iterator that calls function to passed element
I am often writing code like the following (here int and double are just example, types are usually pointers) 我经常在编写如下代码(这里的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));
Since we don't have transform_if
I would like to know if there is a way to do this by definining some special iterator: 由于我们没有
transform_if
所以我想知道是否有办法通过定义一些特殊的迭代器来做到这一点:
template<typename T>
struct inserterStaticCast
{
// not sure what to put here...
}
Then I could write code like 然后我可以写像
std::vector<double> vc(a.size());
std::copy_if(a.begin(), a.end(), inserterStaticCast<double>(vc), &valid);
I would also be interested in the backInserterStaticCast
version. 我也会对
backInserterStaticCast
版本感兴趣。
Is this possible in C++11? 在C ++ 11中可能吗?
Thank you 谢谢
A few clarifications... 一些澄清...
I cannot use boost. 我不能使用升压。 And to again in this case int and double are just for illustration, in the general case I do need a cast, usually something like
static_cast<derived *>(base_ptr)
. 再次在这种情况下,int和double只是为了说明,在一般情况下,我确实需要
static_cast<derived *>(base_ptr)
,通常类似于static_cast<derived *>(base_ptr)
。
I think you want boost's function_output_iterator
. 我认为您需要boost的
function_output_iterator
。 In your example it would be 在您的示例中
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);
Which makes more sense when there isn't an implicit conversion between the two types, such as with Base *
-> Derived *
conversion 当两种类型之间没有隐式转换时,例如使用
Base *
-> Derived *
转换,这更有意义
You can do filtering with std::copy_if
and std::back_inserter
: 您可以使用
std::copy_if
和std::back_inserter
进行过滤:
std::vector<double> vc;
std::copy_if(va.begin(), va.end(), std::back_inserter(vc), valid);
Or use boost::range::adaptors::filtered
(same example problem as yours): 或使用
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));
}
Note that conversion of int
to double
is implicit and doesn't require a cast. 请注意,将
int
转换为double
是隐式的,不需要强制转换。
If you do need a conversion, just throw in transformed
: 如果确实需要转换,则只需输入
transformed
:
auto vb = boost::copy_range<std::vector<double>>(va
| filtered(valid)
| transformed([](int a) { return static_cast<double>(a); })
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.