我想了解何时使用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表达式中,p
和a
必须颠倒它们的用法。
答案 0 :(得分: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
的第一个参数。在手动滚动版本中,您的(符合标准的)并行性选择已经消失。
答案 1 :(得分:2)
关于分配,这是std::back_inserter
的作用。
您还可以在std::transform
来电中设置目标向量vComplex
的大小并使用std::begin
:
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。