2017-06-27 6 views
2

"WolframLibrary.h"構造体を使用して複素数を表し:2つの要素の配列の間でstd :: complexを変換します。

typedef struct {double ri[2];} mcomplex; 
#define mcreal(mc) (((mc).ri)[0]) 
#define mcimag(mc) (((mc).ri)[1]) 

二つの要素の単なる配列です。標準ライブラリー・ヘッダー<complex>は、それを別の方法で定義します。コンパイラが=演算子を使用して2つの間で自動的に変換されるようにしたいのですが、どうすればよいか分かりません。

mcomplex z1 = {3.2, 1.1}; // <-- this is z1 = 3.2 + 1.1 I 
std::complex<double> z2(-4.0, 0.5); // <-- this is z2 = -4.0 + 0.5 I 

仮定どのように私は私のプログラムでz1 = z2mcreal(z1) = real(z2); mcimag(z1) = imag(z2);を意味コンパイラに指示し、その逆のですか?

答えて

2

z1 = z2; 

を使用できるようにする最も簡単な方法はstd::complex<double>からmcomplexに変換コンストラクタを提供することです。その後

、あなたが使用することができます。

std::complex<double> z2(-4.0, 0.5); 
mcomplex z1 = z2; 

または

mcomplex z1 = {3.2, 1.1}; 
std::complex<double> z2(-4.0, 0.5); 
z1 = z2; 

操作に他の方法を使用することができるようにするために、あなたはにmcomplexからユーザ定義の変換演算子を提供する必要がありますstd::complex<double>

最後に、typedef struct {...} mcomplex;を使用する必要はありません。ちょうど使用するstruct mcomplex { ... };

私のために成功したプログラムです。意図的にmainが空であることに注意してください。それはちょうどmcomplexstd::complex<double>の間の法的操作を示しています。

#include <complex> 

struct mcomplex 
{ 
    mcomplex(double re = 0, double im = 0) 
    { 
     ri[0] = re; 
     ri[1] = im; 
    } 

    // Converting constructor. 
    mcomplex(std::complex<double> const& c) : mcomplex(c.real(), c.imag()) {} 

    // User defined conversion operator 
    operator std::complex<double>() const 
    { 
     return {ri[0], ri[1]}; 
    } 

    double ri[2]; 
}; 

void test1() 
{ 
    std::complex<double> z2(-4.0, 0.5); 
    mcomplex z1 = z2; 
    (void)z1; // Shut up the compiler 
} 

void test2() 
{ 
    mcomplex z1 = {3.2, 1.1}; 
    std::complex<double> z2(-4.0, 0.5); 
    z1 = z2; 
} 

void test3() 
{ 
    mcomplex z1 = {3.2, 1.1}; 
    std::complex<double> z2 = z1; 
    (void)z2; // Shut up the compiler 
} 

void test4() 
{ 
    mcomplex z1 = {3.2, 1.1}; 
    std::complex<double> z2(-4.0, 0.5); 
    z2 = z1; 
} 

int main() 
{ 
} 

あなたがmcomplexの定義を変更するオプションを持っていない場合は、あなたの最良のオプションは、変換を行うために、非メンバ関数のカップルを提供することです。その後、

namespace MyApp 
{ 
    mcomplex to_mcomplex(std::complex<double> const& c) 
    { 
     return mcomplex{c.real(), c.imag()}; 
    } 

    std::complex<double> to_std_complex(mcomplex const& c) 
    { 
     return {c.re[0], c.re[1]}; 
    } 
} 

とこれは非常にいいです

std::complex<double> z1(-4.0, 0.5); 
mcomplex z2 = MyApp::to_mcomplex(z1); 

mcomplex z1 = {3.2, 1.1}; 
std::complex<double> z2 = MyApp::to_std_complex(z1); 
+0

を使用! 'WolframLibrary.h'にあるものを修正してこの作業をする必要があるようですが、これは避けたいものです。 '" WolframLibrary.m "'がすでに読み込まれた後にこの作業をすることは可能ですか? – QuantumDot

+0

@QuantumDot、私は恐れていません。 –

+0

私はちょうどあなたの編集を見て、それは行くために非常に合理的な方法のように見えます。パフォーマンス上の理由から、これらの関数をインライン化することは可能ですか? 'inline mcomplex to_mcomplex(std :: complex const&c)'など... – QuantumDot

関連する問題