什么时候更喜欢for-loop而不是std :: transform,反之亦然

问题描述 投票:4回答:2

我想了解何时使用std :: transform更为实际,并且当旧的for-loop更好时。

这是带有for循环的代码,我想将两个向量组合成一个复杂的向量:

    vector<double> vAmplitude = this->amplitudeData(N);
    vector<double> vPhase = this->phaseData(N);
    vector<complex<double>,fftalloc<complex<double> > > vComplex(N);
    for (size_t i = 0; i < N; ++i)
    {
        vComplex[i] = std::polar(vAmplitude[i], vPhase[i]);
    }

这是我的std :: transform代码

    vector<double> vAmplitude = this->amplitudeData(N);
    vector<double> vPhase = this->phaseData(N);
    vector<complex<double>,fftalloc<complex<double> > > vComplex;
    std::transform(
                begin(vPhase), end(vPhase), begin(vAmplitude),
                std::back_inserter(vComplex),
                [](double p, double a) { return std::polar(a, p); });

请注意,vComplex的分配没有大小,所以我想知道分配何时发生。另外我不明白为什么,在lambda表达式中,pa必须颠倒它们的用法。

c++11 for-loop stl
2个回答
5
投票

支持标准算法的一个考虑因素是它为c++17 alternative execution model versions准备你的代码(和你)。

借用JoachimPileborg的答案,假设您将代码编写为

vector<complex<double>,fftalloc<complex<double> > > vComplex(N);
std::transform(
    begin(vAmplitude), end(vAmplitude), begin(vPhase),
    std::begin(vComplex),
    std::polar);

一段时间后,您意识到这是代码中的瓶颈,您需要并行运行它。因此,在这种情况下,您需要做的就是将std::execution::par{}添加为std::transform的第一个参数。在手动滚动版本中,您的(符合标准的)并行性选择已经消失。


2
投票

关于分配,这就是std::back_inserter所做的。

您还可以设置目标矢量vComplex的大小,并在std::begin调用中使用std::transform

vector<complex<double>,fftalloc<complex<double> > > vComplex(N);
std::transform(
            begin(vPhase), end(vPhase), begin(vAmplitude),
            std::begin(vComplex),
            [](double p, double a) { return std::polar(a, p); });

至于lambda中的参数的反转,这是因为你使用vPhase作为std::transform调用中的第一个容器。如果你改为使用vAmplitude而你可能只传递了指向std::polar的指针:

std::transform(
            begin(vAmplitude), end(vAmplitude), begin(vPhase),
            std::begin(vComplex),
            std::polar);

最后,至于什么时候打电话给std::transform,在大多数情况下更多的是个人问题。在尝试自己做所有事情之前,我个人更喜欢使用the standard algoritm functions

© www.soinside.com 2019 - 2024. All rights reserved.