コードでJUCEライブラリといくつかのBoostヘッダーの両方を使用しています。 Juceは「T」をマクロ(うめき声)として定義し、Boostはテンプレート定義で「T」を使用することがよくあります。その結果、Boostヘッダーの前に何らかの方法でJUCEヘッダーを含めると、プリプロセッサがBoostコードのJUCEマクロを展開し、コンパイラが絶望的に失われます。
インクルードを正しい順序に保つことはほとんどの場合難しいことではありませんが、他のクラスを含むJUCEクラスがあり、チェーンのどこかにBoostが含まれている場合、およびその前のファイルがある場合は注意が必要です。あなたが困っていることを含むJUCEが必要でした。
これを修正するための私の最初の希望は
#undef T
boostのインクルードの前。しかし、問題は、それを再定義しないと、他のコードが「T」が宣言されていないことを混乱させることです。
それから私は多分私がそのようにいくつかの循環#defineトリックをすることができると思いました:
// some includes up here
#define ___T___ T
#undef T
// include boost headers here
#define T ___T___
#undef ___T___
醜いですが、うまくいくかもしれないと思いました。
残念ながら違います。 「T」をマクロとして使用している場所でエラーが発生する
'___T___' was not declared in this scope.
これら2つのライブラリを確実に連携させる方法はありますか?
Greyfadeが指摘したように、プリプロセッサは非常に単純な生き物であるため、___T___
トリックは機能しません。別のアプローチは、プラグマディレクティブを使用することです。
// juice includes here
#pragma Push_macro("T")
#undef T
// include boost headers here
#pragma pop_macro("T")
これはMSVC++で機能するはずであり、GCCは互換性のためにpop_macro
とPush_macro
のサポートを追加しました。技術的には実装に依存しますが、一時的に定義を抑制する標準的な方法はないと思います。
問題のあるライブラリを別のインクルードでラップし、#define Tを内部にトラップできますか?
例えば:
JUICE_wrapper.h:
#include "juice.h"
#undef T
main.cpp:
#include "JUICE_wrapper.h"
#include "boost.h"
rest of code....
それから私は多分私がそのようにいくつかの循環#defineトリックをすることができると思いました:
Cプリプロセッサはこのようには機能しません。プリプロセッサシンボルは、関数を定義するときにシンボルに意味が与えられるのと同じ意味で定義されていません例。
プリプロセッサをテキスト置換エンジンと考えると役立つ場合があります。シンボルが定義されると、ファイルの終わりまで、または未定義になるまで、まっすぐなテキスト置換として扱われます。その値はどこにも保存されないため、コピーできません。したがって、#undef
を実行した後にT
の定義を復元する唯一の方法は、コードの後半の新しい#define
でその値を完全に再現することです。
あなたができる最善のことは、単にBoostを使用しないか、JUCEの開発者にT
をマクロとして使用しないように請願することです。 (または、最悪の場合、マクロの名前を変更して自分で修正してください。)