我在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
。
答案 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