2012-05-10 7 views
9

次のコードはC言語ではうまくコンパイルされて実行されますが(少なくとも 'gcc -std = gnu99'に従います)、C++でコンパイルできません。 "行5:エラー:doubleをdoubleに変換できません。複合体 'を初期化します。なぜ誰が知っていますか?Cの複素数C++?

#include "/usr/include/complex.h" 
#include <stdio.h> 

int main(int argc, char * argv[]) { 
    double complex a = 3; // ERROR ON THIS LINE 
    printf("%lf\n", creal(a)); 
    return 0; 
} 

私はC++で複素数を行うための別の方法があり実現し、それは私が与えられたレガシーコードは、物事を行う方法ですので、私は、C++でC複素数を使用する必要があります。あなたが助けることができればありがとう!

+4

しかし、実際に、_why_あなたが使用したくない[ 'のstd ::複雑な<>'](のhttp:// en.cppreference.com/w/cpp/numeric/complex)? – ildjarn

+2

FTR、 '-std = gnu99'は本当に** C **のためのフラグではありません。それは「GNUの考えが良い考えだが、それがあるかどうかは解釈のためのものだ」というものです。あなたが** C **を望むなら '-std = c99'が望ましいです。 –

+0

ildjarn:残念ながら、私が使っているライブラリはC++でC99の複素数を使用しています。このようにプロジェクトを開始するのは賢明ではないようですが、これは私が作業しなければならないコードです。 Martinho:それは本当です。私はテストを行ったはずです-std = c99 – iloveponies

答えて

10

複雑なためにCキーワードを使用します。_Complexを。 C++では、(テンプレート)クラスとしてcomplexを使用しています。 crealがどこにあるのか分かりません。コメントを外します。

#include <complex.h> 
#include <cstdio> 

int main(int argc, char * argv[]) { 
    double _Complex a = 3.0 + 0.0I; // DECLARATION WORKS NOW - NOTE ASSIGNMENT MUST HAVE IMAG PART 
    //printf("%lf\n", creal(a)); 
    return 0; 
} 

これはgccで動作します(g ++でコンパイルされました)。廃止された.hヘッダーに関する警告が出ました。

Hereは、複素数を使用したC++およびCとの非標準互換性を示すメールトレイルへのリンクです。 C++ 11では、C++コンプレックスとC _Complexesのレイアウト互換性が必要です。

私は現在C++でcrealなどを調べています。私は標準で何も見つけていない。 C++とCの間でいくつかのソースの互換性を提供する努力があるように見えるので、creal、cpowなどはTR2にライブラリの提案を追加する可能性があります。

+0

ありがとう!!!!!あなたが言ったことから、私は解決策を得ることができました。スタックオーバーフローではまだソリューションを投稿できませんが、虚数部分を代入に追加する必要があります。 – iloveponies

9

Compatibility of C and C++

Several additions of C99 are not supported in C++ or conflict with C++ features, such as variadic macros, compound literals, designated initializers, variable-length arrays, and native complex-number types. The long long int datatype and restrict qualifier defined in C99 are not included in the current C++ standard, but some compilers such as the GNU Compiler Collection[4] provide them as an extension. The long long datatype along with variadic templates, with which some functionality of variadic macros can be achieved, are present in the new C++ standard, C++11. On the other hand, C99 has reduced some other incompatibilities by incorporating C++ features such as // comments and mixed declarations and code.

15

C++コンパイラは、_Complexキーワードを拡張子(およびいくつかのもの)としてサポートすることを選択できますが、移植性がありません。ポータブルなC++ソリューションを使いたい場合は、残念ながらC++のstd :: complexテンプレートを使用する必要があります。

良いニュースは、C++ std :: complex numbersはCの複素数と互換性があることが保証されています(つまり、あるものへのポインタは常に他のものへのポインタに変換でき、正しいことが起こります)、つまり、Cの複雑な値を期待するCライブラリと相互運用する必要がある場合は、何の問題もありません。

C11:

Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.

C++ 11:

If z is an lvalue expression of type cv std::complex<T> then:

— the expression reinterpret_cast<cv T(&)[2]>(z) shall be well-formed,

reinterpret_cast<cv T(&)[2]>(z)[0] shall designate the real part of z , and

reinterpret_cast<cv T(&)[2]>(z)[1] shall designate the imaginary part of z .

+0

保証はどこにありますか(「C++ std ::複素数はC99複素数との互換性が保証されています」)?以下のレスポンス(http://stackoverflow.com/a/10540288/2189128)では、正反対であると言われる非正規ソース(Wikipedia)を引用しています。 – Jeff

+2

@ジェフ:ウィキペディアのリンクは、私の主張に実際に矛盾しません。それらは異なるタイプですが、同じメモリレイアウトとアラインメント要件を持つことが保証されています。私は自分の答えに適切な言及を加えました。 –