在这种情况下可以避免循环吗?

时间:2014-11-28 22:26:13

标签: c++

我有一个vector<A>,A有一个字段A :: foo。 我想创建一个向量元素是&#34; foo&#39; s&#34;先前的矢量。当然我可以遍历向量的元素,但在STL或其他主要库中是否有直接实现?

3 个答案:

答案 0 :(得分:3)

可能这应该有效

vector<A> vA; // this is your vector<A>, assumed to contain some `A`'s
...
vector<Foo> vFoo; // here is where we extract the Foo's
std::transform(std::begin(vA), std::end(vA), std::back_inserter(vFoo), 
               [](const A& param){return param.foo});

答案 1 :(得分:1)

您可以使用<algorithm>中的std::transform

#include<algorithm>

std::vector<A> as;
// fill it
std::vector<A::foo_type> foos;
foos.resize(as.size());
std::transform(as.begin(), as.end(), foos.begin(), [](const &A) { return A.foo; });

答案 2 :(得分:1)

你可以使用std :: transform,但在这种情况下,我认为基于for循环的范围更具可读性,并且应该至少与使用STL算法一样有效。


编辑: 为了说明我的观点:

struct Foo {};

struct Bar {
    Foo foo;
};

int main() {
    vector<Bar> bars(10);
    vector<Foo> foos1, foos2, foos3;

    foos1.reserve(bars.size());
    for (const auto& e : bars) { // this will become 'for (e:bars)' in the future
        foos1.push_back(e.foo);
    }

    foos2.resize(bars.size());
    transform(bars.begin(), bars.end(), foos2.begin(), [](const Bar& bar) { return bar.foo; });

    foos3.reserve(bars.size());
    transform(bars.begin(), bars.end(), back_inserter(foos3), [](const Bar& bar){return bar.foo; });

}

在我看来,循环版本更容易阅读(但我承认这可能是一个品味问题)。

不要误会我的意思,我确实喜欢算法,但在非常简单的情况下,他们的语法开销并没有减轻它的重量。


EDIT2: 某些处理器有gather instruction指令。有趣的是,一个典型的编译器是否会产生这些以及在哪些条件下。