2017-06-27 6 views
2

"WolframLibrary.h" stellt komplexe Zahlen unter Verwendung des struct:Konvertieren von std :: complex zwischen Array von zwei Elementen.

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

die nur eine Anordnung von zwei Elementen ist. Der Header der Standardbibliothek <complex> definiert es anders. Ich möchte den Compiler automatisch zwischen den beiden mit dem = Operator konvertieren, aber ich weiß nicht wie. Angenommen

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 

Wie sage ich dem Compiler, dass z1 = z2 in meinem Programm bedeutet mcreal(z1) = real(z2); mcimag(z1) = imag(z2); und umgekehrt?

Antwort

2

Die einfachste Art und Weise der Lage sein, eine Umwandlung Konstruktor von std::complex<double> zu mcomplex verwenden

z1 = z2; 

zur Verfügung zu stellen.

Dann können Sie verwenden:

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

oder

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

Um die Vorgänge in die andere Richtung verwenden zu können, müssen Sie von mcomplex einen benutzerdefinierten Konvertierungsoperator zur Verfügung zu stellen std::complex<double>.

Schließlich muss typedef struct {...} mcomplex; nicht verwendet werden. Verwenden Sie einfach struct mcomplex { ... };

Hier ist Programm, das erfolgreich für mich baut. Bitte beachten Sie, dass main absichtlich leer ist. Es zeigt nur die legalen Operationen zwischen mcomplex und std::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() 
{ 
} 

Wenn Sie die Möglichkeit haben, nicht die Definition von mcomplex modifizieren, Ihre beste Möglichkeit ist, einige nicht-Member-Funktionen bereitzustellen, um die Conversions zu tun.

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

und dann

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

und

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

Das ist sehr schön verwenden! Es scheint, dass ich modifizieren muss, was in 'WolframLibrary.h' ist, um diese Arbeit zu machen, die ich lieber vermeiden möchte. Ist es möglich, dies zu tun, nachdem '" WolframLibrary.m "' bereits geladen ist? – QuantumDot

+0

@QuantumDot, fürchte ich nicht. –

+0

Ich habe gerade Ihren Schnitt gesehen, und es sieht nach einem sehr vernünftigen Weg aus. Ist es aus Performance-Gründen möglich, diese Funktionen zu inline zu führen? Ich dachte 'inline mcomplex to_mcomplex (std :: komplex const & c)' etc ... – QuantumDot

Verwandte Themen