在部分副本中使用for_each

时间:2013-10-14 15:14:45

标签: c++11 vector foreach copy mask

我有一些旧的C代码仍然运行得非常快。它所做的一件事就是存储条件所在的数组部分('蒙面'副本)

所以C代码是:

int    *msk;
int     msk_size;
double *ori;
double  out[msk_size];    

...   

for ( int i=0; i<msk_size; i++ )
    out[i] = ori[msk[i]];

当我对这段代码进行“现代化”时,我认为在C ++ 11中有一种方法可以使用不需要使用索引计数器的迭代器。但使用std::for_each甚至std::copy似乎没有更短的方法。 有没有办法在C ++ 11中更简洁地写这个?或者我应该停止查看并保留旧代码吗?

2 个答案:

答案 0 :(得分:1)

我认为您正在寻找std::transfrom

std::array<int, msk_size> msk;
std::array<double, msk_size> out;
double *ori;

....

std::transform(std::begin(msk), std::end(msk), 
               std::begin(out), 
               [&](int i) { return ori[i]; });

答案 1 :(得分:1)

如果您只想对循环进行现代化,并保留orimsk数据,请使用@ YuxiuLi的解决方案。如果您还希望对msk数据的生成进行现代化,则可以将std::copy_if与谓词(此处:仅保留负数的lambda)一起使用以直接过滤元素。

#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>

int main()
{
    auto ori = std::vector<double> { 0.1, -1.2, 2.4, 3.4, -7.1 };
    std::vector<double> out;

    std::copy_if(begin(ori), end(ori), std::back_inserter(out), [&](double d) { return d < 0.0; });
    std::copy(begin(out), end(out), std::ostream_iterator<double>(std::cout, ","));
}

Live Example。这样可以节省msk的中间存储空间。