将STL中的complex<double>转换为fftw_complex时出现问题

16

FFTW手册说明,它的fftw_complex类型与STL中的std::complex<double>类是位兼容的。但这对我来说并不起作用:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx;
   fx = reinterpret_cast<fftw_complex>(x);
}

这个给我报错:

error: invalid cast from type ‘std::complex<double>’ to type ‘double [2]’

我做错了什么?

3个回答

23

关于 fftw_complex 和 C99 以及 C++ 复数类型的位兼容性,其意义并不在于它们可以轻松地相互创建,而是所有取指向 fftw_complex 的指针的 FFTW 函数也可以取指向 c++ std::complex 的指针。因此,最好的方法可能是在整个程序中使用 std::complex<>,并且只在调用 FFTW 函数时将指针转换为这些值:

std::vector<std::complex<double> > a1, a2;
....
....
fftw_plan_dft(N, reinterpret_cast<fftw_complex*>(&a1[0]),
                 reinterpret_cast<fftw_complex*>(&a2[0]),
                 FFTW_FORWARD, FFTW_ESTIMATE);
....

迄今为止最好的选择。 - Mike

8

请将代码重写如下:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx;
   memcpy( &fx, &x, sizeof( fftw_complex ) );
}

我使用过的所有编译器都会优化掉memcpy,因为它是复制一定量(即在编译时已知)的数据。

这样可以避免指针别名问题

编辑:您还可以使用联合来避免严格别名问题,方法如下:

#include <complex>
#include <fftw3.h>
int main()
{
   union stdfftw
   {
       std::complex< double > stdc;
       fftw_complex           fftw;
   };
   std::complex<double> x(1,0);
   stdfftw u;
   u.stdc = x;
   fftw_complex fx = u.fftw;
}

尽管严格来说,这违反了C99规则(不确定是否适用于C++),因为从一个联合体的其他成员中读取数据是未定义的。但它在大多数编译器上都可以工作。个人而言,我更喜欢我的原始方法。

好的,这对我来说没问题!已经有3年没有用纯C编程了 :) 非常感谢。 - galadog
@ galadog memcpy 有必要吗?你为什么不能这样做:std::complex<double> x(1,0);fftw_complex* fx=&x - Andrew Buss
那么对于一个复数数组呢? - pyCthon

7

reinterpret_cast 只适用于指针和引用。所以你需要这样做:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx(*reinterpret_cast<fftw_complex*>(&x));
}

假设fftw_complex有复制构造函数。为避免严格别名问题,应首选Goz的解决方案

2
你上面所做的违反了严格别名规则,应该避免。GCC会警告你这样做,并且如果你开启了严格别名,可能会出现错误。 - Goz
@Goz:你是对的。我添加了一个警告并引用了你的答案。 - Björn Pollex
2
对于引用也适用:fftw_complex fx(reinterpret_cast<fftw_complex&>(x)); - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接