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

Mat*_*ech 5 for-loop stl c++11

我想了解何时使用std :: transform更实用,何时使用老式的for循环更好。

这是带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]);
    }
Run Code Online (Sandbox Code Playgroud)

这是我的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); });
Run Code Online (Sandbox Code Playgroud)

请注意,vComplex的分配没有大小,因此我想知道何时分配。此外,我不明白为什么,在lambda表达式,p并且a必须扭转对他们的使用。

Ami*_*ory 5

支持标准算法的一个考虑因素是,它为c ++ 17替代执行模型版本准备了您的代码(和您自己)。

要借用JoachimPileborg的答案,请说您将代码编写为

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

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


Som*_*ude 3

关于分配,就是这样std::back_inserter

您还可以设置目标向量的大小vComplexstd::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); });
Run Code Online (Sandbox Code Playgroud)

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

std::transform(
            begin(vAmplitude), end(vAmplitude), begin(vPhase),
            std::begin(vComplex),
            std::polar);
Run Code Online (Sandbox Code Playgroud)

最后,至于何时打电话,std::transform在大多数情况下更多的是个人问题。我个人更喜欢在尝试自己做所有事情之前使用标准算法函数。