【问题标题】:Converting std::complex between array of two elements.在两个元素的数组之间转换 std::complex。
【发布时间】:2017-11-30 00:11:50
【问题描述】:

"WolframLibrary.h" 使用结构体表示复数:

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

这只是一个包含两个元素的数组。标准库头文件<complex> 对它的定义不同。我想让编译器使用= 运算符在两者之间自动转换,但我不知道如何。假设

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 = z2 表示mcreal(z1) = real(z2); mcimag(z1) = imag(z2);,反之亦然?

【问题讨论】:

    标签: c++ arrays types


    【解决方案1】:

    最简单的使用方法

    z1 = z2;
    

    是提供一个从std::complex&lt;double&gt;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;
    

    为了能够以其他方式使用这些操作,您需要提供一个用户定义的从mcomplexstd::complex&lt;double&gt; 的转换运算符。

    终于不用typedef struct {...} mcomplex;了。只需使用struct mcomplex { ... };

    这是为我成功构建的程序。请注意,main 故意为空。它只是演示了mcomplexstd::complex&lt;double&gt;之间的合法操作。

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

    【讨论】:

    • 这很好!看来我需要修改 WolframLibrary.h 中的内容以使其正常工作,我更愿意避免这样做。 "WolframLibrary.m" 已经加载后是否可以进行这项工作?
    • @QuantumDot,恐怕不会。
    • 我刚刚看到您的编辑,这看起来是一个非常合理的方法。出于性能原因,是否可以内联这些函数?我在想inline mcomplex to_mcomplex(std::complex&lt;double&gt; const&amp; c) 等等...
    • 其实这并不能编译。 to_mcomplex 的主体不应该只是 return {real(c), imag(c)}; 吗?此外,to_std_complex 似乎没有返回正确的类型,因为std::complex&lt;double&gt; 不是两个元素的数组。它不应该真的返回std::complex&lt;double&gt;(mcreal(c), mcimag(c))吗?
    • @QuantumDot,它对我有用。启用 C++11/C++14 可能是您需要的。见ideone.com/qQIjeJ
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多