2017-05-25 56 views
1

我有一些C++ DSP庫,它們使用complex [T]類型來表示複數。我想從使用std::complex<T>的C++應用程序中調用這些。_Complex和std :: complex之間的C/C++互操作

閱讀N4296this SO answerthis one,和§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)); 

這是編譯器錯誤還是我誤解了一些東西?如果C++代碼使用std::complex<T>類型,那麼如何使用C函數,該函數採用complex [T]參數?目前,我使用骯髒的黑客來解決這個問題,但我更喜歡一種乾淨的方式。

我試着用-std=c++14編譯,以防萬一這個功能錯過了C++ 11(儘管帖子引用了C++ 11標準),但我得到了相同的結果。


26.4複數[complex.numbers]

  1. <complex>定義表示和操縱 複數類模板,以及衆多的功能。

  2. 未指定實例化除float,double或long double之外的任何類型的模板複合體 的影響。專業化complex<float>complex<double>complex<long double>是 文字類型(3.9)。

  3. 如果函數的結果未在數學上定義,或者其 類型的可表示值範圍未定義,則行爲未定義。

  4. 如果z型CV std::complex<T>然後的左值表達式:

    4.1。表達式reinterpret_cast<cv T(&)[2]>(z)應是格式良好的,

    4.2。 reinterpret_cast<cv T(&)[2]>(z)[0]應指定z的實部,並且

    4.3。 reinterpret_cast<cv T(&)[2]>(z)[1]應指定z的虛部。

+0

閱讀了''頭文件中的音符請參照:http://en.cppreference的.com /瓦特/ CPP /報頭:_ 「(已棄用)\t簡單地包括頭 」_ ... _「 (因爲C++ 11)(不建議使用在C++ 17)\t」 _ –

+0

@RichardCritten:你會介意粘貼相關部分的一小部分,所以我們不一定要追查它嗎? –

+0

@RichardCritten:謝謝。在我的情況下,'complex.h'包含在C頭文件中,而不是C++代碼中。我在實驗中添加了它,因爲它將被我的應用程序包含(通過C庫標題) –

回答

4

你的問題是你想轉換爲一個值,而不是引用。標準保證

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

形成良好。它不說

reinterpret_cast<cv T[2]>(z) 

是否有效。爲了使你的代碼編譯,你需要改變投投給它給你

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

Live Example

+0

Ahhhhh我誤解了圓括號的含義! ''cfunc(* reinterpret_cast (z));'編譯(注意在強制轉換後取消引用,如果C庫期望在我的測試用例中使用單個值)。你的回答也解釋了爲什麼在標準中提到z是一個左值。 –

+1

@MarkKCowan是的。這要求它是一個lvaule,所以你可以綁定到參考。 – NathanOliver

+0

如何將一個'std :: complex *'傳遞給一個需要'complex T *'的C函數? –

相關問題