2010-11-18 12 views
12

FFTWマニュアルsaysfftw_complexタイプはSTLのstd::complex<double>クラスとビット互換です。しかし、それは私のために動作しません:問題をキャスティングするSTLコンプレックス<double>〜fftw_complex

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

私が間違っているのは何:

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

これは私にエラーを与えて?

答えて

8

次のようにコードを再書き込み:

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

を、それはデータの、つまりコンパイル時に、一定量をコピーしているので、私が使用したすべてのコンパイラはmemcpyをを最適化します。

これは、pointer aliasing issuesを回避します。

編集:あなたはまた、次のように労働組合を使用して、厳密なエイリアシングの問題を回避することができます

#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; 
} 

(C++わからない)厳密にこのC99規則は労働組合の異なるメンバーからの読み取りとして壊れているが書かれたものにも定義されていません。それはほとんどのコンパイラで動作します。個人的に私は私の元の方法を好む。

+0

これは私にとってはうまくいきます!純粋なCでコーディングしていない3年です:)ありがとう。 – galadog

+0

@galadog memcpyは必要ですか?なぜあなたはこれを行うことができませんでした: 'std :: complex x(1,0); fftw_complex * fx =&x' –

+0

@Andre Boos:厳しいエイリアシングルールが破られているので... – Goz

4

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's solutionが望ましいはずです。

+1

あなたは上記のやることは、厳密なエイリアシング規則を破ると、避けるべきである。したがって、最善のアプローチは、あなたのプログラム全体のstd :: <コンプレックス>を使用し、FFTW関数を呼び出すときにのみ、これらの値へのポインタを変換すると考えられます。 GCCはあなたに警告します。厳密なエイリアシングが有効になっていると、潜在的に壊れてしまいます。 – Goz

+0

@Goz:そうです。私は警告を追加し、あなたの答えに言及しました。 –

+2

参照のためにも動作します: 'fftw_complex fx(reinterpret_cast (x));' – MSalters

18

fftw_complexとC99およびC++複合型のビット互換性の考え方は、相互に簡単に作成できるというわけではありませんが、fftw_complexへのポインタをとるFFTWのすべての関数は、C++ std ::複合体。

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); 
.... 
+0

これまでのところ最良の方法です。 – Mike

関連する問題