在c++中获取指向复向量实部和虚部的指针

Getting pointers to the real and imaginary parts of a complex vector in C++

本文关键字:实部 虚部 指针 向量 c++ 获取 取指      更新时间:2023-10-16

使用标准的c++复数和向量库,我定义了一个复数向量。现在,我想要得到(类型为double *的)指向包含这个复向量的实部和虚部的向量的指针。下面的解决方案可以工作,但是不美观且浪费,因为内存使用量增加了一倍;

using namespace std;
typedef complex<double> cmp;
.
.
int i,m=10;
vector<cmp> C(m);
//Do something to populate the vector C
vector<double> R(m), I(m);
for(i=0; i<m; i++){
 R[i] = C[i].real();
 I[i] = C[i].imag();
}
double * r = &R[0];
double * i = &I[0];

根据c++标准

If z is an lvalue expression of type cv std::complex<T> then:
— the expression reinterpret_cast<cv T(&)[2]>(z) shall be well-formed,
— reinterpret_cast<cv T(&)[2]>(z)[0] shall designate the real part of z, and
— reinterpret_cast<cv T(&)[2]>(z)[1] shall designate the imaginary part of z.
Moreover, if a is an expression of type cv std::complex<T>* and the expression a[i] is well-defined
for an integer expression i, then:
— reinterpret_cast<cv T*>(a)[2*i] shall designate the real part of a[i], and
— reinterpret_cast<cv T*>(a)[2*i + 1] shall designate the imaginary part of a[i].

你可以直接写

using namespace std;
typedef complex<double> cmp;
.
.
int i,m=10;
vector<cmp> C(m);
//Do something to populate the vector C
double * r = &reinterpret_cast<double(&)[2]>( C[0] )[0];
double * i = &reinterpret_cast<double(&)[2]>( C[0] )[1];

下面是一个例子

#include <iostream>
#include <complex>
#include <vector>
int main() 
{
    std::vector<std::complex<double>> v( 1, { 1.1, 2.2 } );
    double * r = &reinterpret_cast<double(&)[2]>( v[0] )[0];
    double * i = &reinterpret_cast<double(&)[2]>( v[0] )[1];
    std::cout << *r << 't' << *i << std::endl;
    return 0;
}

输出为

1.1 2.2

(c++ 03)标准没有定义std::complex<double>的内部是怎样的,但通常它由两个双精度数组成,实部在虚部之前。因此,给定一个std::complex<double>的数组(或std::vector),你不可能得到一个指向全实部数组的指针,而另一个指向全虚部数组的指针:实部和虚部是交错的。如果你真的需要拆分它们,你必须复制所有的元素(就像你已经做的那样)。

但是你为什么要把他们分开呢?把它们传递给某个库的一些例程?也许那个库也支持交错格式?在这种情况下,你可以做reinterpret_cast<double*>(&C[0])。请注意,这是非标准的,但它似乎在大多数情况下都有效。有关更多信息,请参阅广泛使用的fftw-库的文档,其中推荐使用此方法。

如果性能是一个问题,你应该从一开始就把实部和虚部分开,而不是先构造一个std::complex<double>向量。