2017-02-21 7 views
-1

私はアプリケーションのすべての設定にアクセスするための一般設定構造体を1か所で実装しようとしています。アプリの各モジュールには独自の設定クラス/構造体があります。私は一般設定の構造体に各モジュール設定の型を持つメンバを定義したいと思います。簡単にするために、モジュール設定ごとに新しいメンバを作成するREGISTERマクロを定義します。このようなC++マクロを使用して単一クラスのクラスメンバーを定義する

何か:

struct Settings 
{  
    // I know this is not working 
    #define REGISTER_SETTINGS(settings) \ 
      settings _##settings = ##settings(); 
}; 

struct ServerSettings 
{ 
    int port = 8080; 
    string ip = "0.0.0.0"; 
}; 

REGISTER_SETTINGS(ServerSettings); 

struct WindowSettings 
{ 
    int width = 640; 
    int height = 480; 
    string title = "window"; 
}; 

REGISTER_SETTINGS(WindowSettings); 

最後に私の設定構造体は次のようになります。

struct Settings 
{ 
    ServerSettings _ServerSettings = ServerSettings(); 
    WindowSettings _WindowSettings = WindowSettings(); 
}; 

私はそこでマクロ展開を取得する必要がありますか見当もつかない。

+7

C++でマクロを使用するための1語のガイドです。**はありません**。 –

+0

マクロからセミコロンを削除する必要があります。 – StoryTeller

+0

なぜstruct内にマクロを定義しますか? – user463035818

答えて

2

マクロは使用しないでください。あなたがプログラマであるので、私の目には意味がないでしょうあなたはプログラマですので、その2行をSettings構造体に書き込んでください... しかし、このような関数をインライン関数。あなたはこのように行うことができます

0

#define REGISTER_SETTINGS(settings) \ 
     settings _##settings = settings(); 

ノートなし '##' settings()前。

しかし:

  1. としては、すでにコメントで指摘した:より良いない使用マクロを実行します。
  2. これ例えば、あなたが期待するものをもたらさないであろう。

    struct Settings 
    { 
        ServerSettings _ServerSettings = ServerSettings(); 
        WindowSettings _WindowSettings = WindowSettings(); 
    }; 
    

    が、それは、マクロが呼び出された場所にオブジェクトを作成します。

    struct Settings 
    ... 
    struct ServerSettings 
    ... 
    ServerSettings _ServerSettings = ServerSettings(); 
    
    struct WindowSettings 
    ... 
    WindowSettings _WindowSettings = WindowSettings(); 
    
  3. 私のようないくつかのcreational patternを使用することをお勧めし(要約)工場または工場の方法。

1

他の人も述べたように、マクロを完全に避けるほうがよいです。

はしかし、尋ねたとして、質問に対応するために....

を他struct型のインスタンスであるメンバーを持つstruct型を宣言するために、コンパイラはすでに、これらの含まれているタイプの宣言を見ている必要があります。単純に定義の順序を変更してください。

struct ServerSettings 
{ 
    int port = 8080; 
    string ip = "0.0.0.0"; 
}; 

struct WindowSettings 
{ 
    int width = 640; 
    int height = 480; 
    string title = "window"; 
}; 

struct Settings 
{  
#define REGISTER_SETTINGS(settings) \ 
     settings _##settings = ##settings() 

    REGISTER_SETTINGS(ServerSettings); 
    REGISTER_SETTINGS(WindowSettings); 

     // etc 

#undef REGISTER_SETTINGS 
}; 

#undefstruct Settingsの定義外で使用されているマクロを防止します。

ただし、1つの重要な問題があります。これにより、アンダースコアと大文字で始まる識別子が作成されます。このような識別子はC++標準で予約されており、コードを使用するとコードが未定義の動作をします。これを回避する1つの方法は、マクロを

#define REGISTER_SETTINGS(settings) \ 
    settings a_##settings = ##settings() 

に変更することで、予約済み識別子の作成を防止します。

第二に、宣言

Type name = Type(); 

基本的にデフォルト-を初期化nameは、そうあなたは、さらに私のよう

#define REGISTER_SETTINGS(settings) \ 
    settings a_##settings 

にマクロを簡素化することができます

Type name; 

と機能的に同等です最初はそう言っていましたが、マクロ全体を避ける方がいいですy。マクロはこれを行うという事実を単に不明瞭にします。

// definitions of ServerSettings and WindowSettings here 

struct Settings 
{  
    ServerSettings a_ServerSettings;  
    WindowSettings a_WindowSettings; 
}; 

これは、使用しようとしているマクロの難読化がはるかに簡単です。明らかに、Settingsのメンバの命名規則を自由に使うことができます。

関連する問題