Reputation: 435
"WolframLibrary.h"
represents complex numbers using the struct:
typedef struct {double ri[2];} mcomplex;
#define mcreal(mc) (((mc).ri)[0])
#define mcimag(mc) (((mc).ri)[1])
which is just an array of two elements. The standard library header <complex>
defines it differently. I want to make the compiler automatically convert between the two using the =
operator, but I don't know how. Suppose
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
How do I tell the compiler that z1 = z2
in my program means mcreal(z1) = real(z2); mcimag(z1) = imag(z2);
, and vice versa?
Upvotes: 2
Views: 354
Reputation: 206577
The simplest way to be able to use
z1 = z2;
is to provide a converting constructor from std::complex<double>
to mcomplex
.
Then, you can use:
std::complex<double> z2(-4.0, 0.5);
mcomplex z1 = z2;
or
mcomplex z1 = {3.2, 1.1};
std::complex<double> z2(-4.0, 0.5);
z1 = z2;
In order to be able to use the operations the other way, you need to provide a user defined conversion operator from mcomplex
to std::complex<double>
.
Finally, there is no need to use typedef struct {...} mcomplex;
. Just use struct mcomplex { ... };
Here's program that builds successfully for me. Please note that main
is empty on purpose. It just demonstrates the legal operations between mcomplex
and 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()
{
}
If you don't have the option of modifying the definition of mcomplex
, your best option is to provide couple of non-member functions to do the conversions.
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]};
}
}
and then use
std::complex<double> z1(-4.0, 0.5);
mcomplex z2 = MyApp::to_mcomplex(z1);
and
mcomplex z1 = {3.2, 1.1};
std::complex<double> z2 = MyApp::to_std_complex(z1);
Upvotes: 2