【问题标题】:C/C++ interop between _Complex and std::complex_Complex 和 std::complex 之间的 C/C++ 互操作
【发布时间】:2017-10-26 01:56:55
【问题描述】:

我有一些 C DSP 库,它们使用 complex [T] 类型来表示复数。我想从使用 std::complex<T> 的 C++ 应用程序中调用它们。

在阅读了this SO answerthis one,以及N4296的§26.4之后,我尝试了一个实验:

extern "C" {
#include <complex.h>
// Using _Complex or __complex__ since C's "complex" type doesn't exist in C++
void cfunc(_Complex float x);
}
#include <complex>

void test()
{
        std::complex<float> z;
        cfunc(reinterpret_cast<float[2]>(z));
}

并尝试使用CXXFLAGS="-std=c++11" 编译它。我从 GCC 6.3.1 得到以下信息:

error: invalid cast from type ‘std::complex<float>’ to type ‘float [2]’
  cfunc(reinterpret_cast<float[2]>(z));

这是一个编译器错误还是我误解了什么?给定使用std::complex&lt;T&gt; 类型的C++ 代码,如何使用带有complex [T] 参数的C 函数?目前,我使用一种肮脏的技巧来解决这个问题,但我更喜欢一种干净的方法。

我尝试使用 -std=c++14 进行编译,以防此功能以某种方式错过了 C++11(尽管帖子引用了 C++11 标准)但我得到了相同的结果。


26.4 复数 [complex.numbers]

  1. 标题&lt;complex&gt; 定义了一个类模板,以及用于表示和操作的许多函数 复数。

  2. 为浮点、双精度或长双精度以外的任何类型实例化模板复合体的效果 未指定。专业化complex&lt;float&gt;complex&lt;double&gt;complex&lt;long double&gt; 是 文字类型 (3.9)。

  3. 如果函数的结果未在数学上定义或不在其可表示值的范围内 类型,行为未定义。

  4. 如果 z 是 cv std::complex&lt;T&gt; 类型的左值表达式,则:

    4.1。表达式reinterpret_cast&lt;cv T(&amp;)[2]&gt;(z) 应该是格式良好的,

    4.2。 reinterpret_cast&lt;cv T(&amp;)[2]&gt;(z)[0] 应指定 z 的实部,并且

    4.3。 reinterpret_cast&lt;cv T(&amp;)[2]&gt;(z)[1] 应指定 z 的虚部。

【问题讨论】:

  • 阅读&lt;complex.h&gt; 头文件的注释:en.cppreference.com/w/cpp/header : " (已弃用)仅包含头文件 " ... " (C++11 起)(C++17 中已弃用)"
  • @RichardCritten:您介意粘贴相关部分的 sn-p,这样我们就不必全部追查了吗?
  • @RichardCritten:谢谢。就我而言,complex.h 包含在 C 标头而不是 C++ 代码中。我在实验中添加了它,因为它会包含在我的应用程序中(通过 C 库头文件)

标签: c++ c c++11


【解决方案1】:

你的问题是你试图转换为一个值而不是一个引用。该标准保证

reinterpret_cast<cv T(&)[2]>(z)

结构良好。它没有说

reinterpret_cast<cv T[2]>(z)

有效。为了使您的代码编译,您需要将强制转换为强制转换为提供给您的参考

cfunc(reinterpret_cast<float(&)[2]>(z));

Live Example

【讨论】:

  • 啊啊啊我误解了圆括号的意思! ` cfunc(*reinterpret_cast(z));` 编译(请注意转换后的取消引用,如果 C 库期望单个复数,如我的测试用例中的值)。您的回答还解释了为什么在标准中提到 z 是左值。
  • @MarkKCowan 是的。这要求它是一个 lvaule,以便您可以绑定到引用。
  • 如何将std::complex&lt;T&gt; * 传递给采用complex T * 的C 函数?
  • @MarkKCowan 应该可以使用:coliru.stacked-crooked.com/a/a598181914271d44
  • 如果该函数采用float(*)[2] 参数,则有效,但对于采用指向复杂的指针的(C)函数,它似乎不起作用:coliru.stacked-crooked.com/a/8a08b9e918722da5
猜你喜欢
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 2018-03-13
相关资源
最近更新 更多