将C ++ 11 complex <float> *转换为C float复合体*

时间:2018-06-20 18:45:49

标签: c++ c

我在C ++ 11中使用了一系列复杂的浮点数:

std::complex<float> *cx;

我正在尝试使用一个采用C风格复杂浮点数的旧库:

float complex *cx;

我认为问题的部分原因在于标头中的库#includes <complex.h>,而我的C ++ 11代码中的库#include <complex>

当我尝试这样做时:

std::complex<float> *cpp = new std::complex<float>[100];
complex float *c = reinterpret_cast<complex float*>(cpp);
c_process(c); // c_process(complex float *c)    [ c library function ]

我得到:

error: expected ';' before 'float'   
complex float *c = reinterpret_cast<complex float*>(cpp);
        ^

关于C ++ 11和“复杂”一词,这里发生了一些独特的事情。

我已按照要求编辑了问题,以澄清问题。

一种解决方案: 仅当您可以修改其他库的标头时,此解决方案才有效。

由于关闭了此问题的权力(尽管我认为这是一个非常好的解决方案,很难找到解决方案),所以我做了以下事情:

由于<complex.h>有一个#define complex _Complex,而<complex>包含一个class complex,所以在同时包含两个标头时会有一些冲突。

我必须在我的代码和其他库的头文件中的所有地方,将所有float complex*更改为float _Complex*。对我来说,这是很大的改变。

之所以可行,是因为在以任何c ++标准为其自己的Makefile进行编译时,其他库complex仍被定义为_Complex,但是我们要求我们停止使用complex

2 个答案:

答案 0 :(得分:3)

这种不兼容性仅是语法,两种语言都保证其复杂类型与float[2](或double[2]等)具有相同的布局。因此,您可以在具有宏cfloat的情况下在两者之间进行中介,该宏根据扩展语言而定义。类似于

#ifdef __cplusplus
typedef std::complex<float> cfloat;
#else
typedef float _Complex cfloat;
#endif

然后在所有函数原型中使用此cfloat

答案 1 :(得分:3)

这可能很容易。 std::complex定义了复杂对象的存储顺序,并提供了访问复杂对象数组的实部和虚部的方法。如果顺序与旧图书馆中的顺序相同,那么您可能很幸运

来自http://en.cppreference.com/w/cpp/numeric/complex

  

对于类型为z的任何对象complex<T>reinterpret_cast<T(&)[2]>(z)[0]z的实部,reinterpret_cast<T(&)[2]>(z)[1]z的虚部

  

对于指向名为complex<T>的{​​{1}}数组元素和任何有效数组索引p的任何指针,i是复数{{ 1}},而reinterpret_cast<T*>(p)[2*i]是复数p[i]

的虚部

因此,您可以简单地引用与C99兼容的reinterpret_cast<T*>(p)[2*i + 1]

  

`std :: complex * cx1 = reinterpret_cast *> cx;

由于同时包含p[i]float _Complex *cx时发生冲突,一种方法是从C标头中提取基本声明,并将其与使用的C函数声明一起包含在“ C” extern语句中像这样:

complex

此代码特定于Visual Studio C和C ++。 VSC与C99不兼容,但是数据结构相同,因此您将需要为使用任何C编译器的复杂float提取特定的声明。

这将是VC中称为“ C”代码的示例。

complex.h