2012-03-23 8 views
2

関数の結果に基づいてC++プリプロセッサマクロを作成することはできますか?関数用のプリプロセッサマクロを作成する方法はありますか?

例えば、私は、プリプロセッサマクロ定義で動的に画面の高さを節約したいと思います:

#if SCREEN_HEIGHT < 1200 
    #define TOP_COORD  200 
    #define BOTTOM_COORD 500 
    #define LEFT_COORD 0 
    #define RIGHT_COORD 1280 
#else 
    #define TOP_COORD  1100 
    #define BOTTOM_COORD 1400 
    #define LEFT_COORD 0 
    #define RIGHT_COORD 1280 
#endif 

#define SCREEN_HEIGHT GetSystemMetrics(SM_CYVIRTUALSCREEN) 

は、その後、私は画面の高さに基づいて値を設定するために、結果を使用したいです

SCREEN_HEIGHTが正しく定義されていないように見えるため、これは機能しません。

これを実行するより良い方法はありますか?これも可能ですか?可能であれば、ヘッダーファイル内のこの画面高さ情報を得ることができるようにしたいと考えています。これは、従来のコードの大きな部分です。

答えて

5

マクロは、実際のコードがコンパイルされる前に、概念的には少なくともプリプロセッサで評価され、#ifなどの式はプリプロセッサ式でなければなりません。プログラムが実行されるまで画面の高さを知ることはできません。

+0

ありがとうございます。 – devurs

2

いいえ、できません。アプリケーションが実行される画面のプロパティに応じて、コンパイル時のデシジョンをどのようにすると思いますか?コンパイル時にそれを知ることはできません。

2

通常、実際の関数は実行時にのみ呼び出されます。 sizeof(およびgeneralized constant expressions - 注釈のために@Pubbyのおかげでさえ)のような関数のようなものは、の前処理段階の後にコンパイラによって評価されます。この時までに、プリプロセッサのすべてのものがコード内で置き換えられました。コンパイラは#ifのようなものについては考えていません。したがって、あなたが望むものはマクロを使用することはできません。

テンプレートを使用すると可能です。 実際の画面の高さは実行時まで知ることができないため、この場合は2番目の考えではありません。

座標値を定数として格納するように構造体を定義し、マップや他の形式のコレクションにこれらを格納し、実際の画面の高さを知っているときに実行時に動的に参照することができます。

+1

コンパイル時に関数を呼び出すことができます。 – Pubby

+0

@Pubby、ありがとう、私はそれを知らなかった。対応する記事へのリンクを追加しました。 –

0

GetSystemMetricsがマクロであれば、これを行うことができます。 GetSystemMetricsconstexprの場合は、形質を使用できます。

しかし、GetSystemMetricsは通常の関数なので、通常のC++で作業する必要があります。

struct system_metrics_ { 
    int top, bottom, left, right; 

    system_metrics_() 
    { 
    if (GetSystemMetrics(SM_CYVIRTUALSCREEN) < 1200) { /* first case */ } 
    else { /* second case */ } 
    } 
}; 

// define this method outside the header 
const system_metrics_& system_metrics() { static system_metrics_ sm; return sm; } 

// legacy code 
#define TOP_COORD  (system_metrics().top) 
#define BOTTOM_COORD (system_metrics().bottom) 
#define LEFT_COORD (system_metrics().left) 
#define RIGHT_COORD (system_metrics().right) 
関連する問題