2015-08-23 222 views
0

我想定義類並將其註冊爲一個宏。也就是說,運行一些運行時代碼來註冊類型節點,以便稍後可以遍歷它們。C++靜態成員初始化

#define DUMMY_REG(name,strname) \ 
    struct name { template <class Any> name(Any&&,int i = \ 
     registerType()) {} name() {} \ 
     static int registerType() {  \ 
      static int res = registerTypeInMap(strname,\ 
       makeTypeNodeFunction<name>(strname));\ 
      return res;\ 
     }\ 
     static int s_var = registerType();\ 
    }; 

所以,基本上我有靜態s_var並初始化它,我要運行一些功能,爲它的副作用(其中註冊類型)。但是,當然,我不能初始化s_var內聯。我必須在課堂外進行。這是一個問題,因爲我想窩類型這樣的:

struct ClassHolder { 
    DUMMY_REG(TypeA,"Runtime_name_for_TypeA"); 
    DUMMY_REG(TypeB,"Runtime_name_for_TypeB"); 
}; 

在宏結束時,我也寫不了,因爲它仍然是在類範圍。我如何確保在執行main之前運行一些靜態代碼來定義和註冊某個類型?

我想避免的主要事情是多餘的重複,就像一個聲明類和一個宏註冊類型 - 這是多餘的和愚蠢的。

+3

爲什麼不提供另一個模板,比如'template struct DummyReg {}'而不是宏? –

+0

忽略宏觀怪異,你所要做的就是將靜態定義爲* something *,如果你願意,可以通過函數改變它們,至少只要它們不是const const。在任何情況下,宏都不應該用於這個。 –

+0

@WilliamKappler我想只寫一次DUMMY_REG(mytime,「runtimename」),根本不用擔心它,你以前說過它的工作方式,我會定義結構並在另一個地方註冊它們,我希望一切一氣呵成。只要我進入主要我想要類型準備就緒。 –

回答

0

這就是我現在的解決方法(也許人們在評論中暗示了這種方式,我不確定)。基本上,我使用了一個輔助類型和一個模板,該模板調用一個不連續的函數來獲取int作爲副作用,然後,您需要使用該int,以便它被實例化(編譯器可以忽略它),所以我使用該int作爲構造函數中的默認參數。不知道這將如何擴展,希望這是跨平臺的。

#define DUMMY_REG(name,strname) \ 
    struct name { template <class Any> name(Any&&,int reg = Regger::s_sideEffect) {} \ 
     TypeRegger<name> Regger; \ 
     name() {} \ 
     static int registerType() {  \ 
      static int res = registerTypeInMap(strname,\ 
       makeTypeNodeFunction<name>(strname));\ 
      return res;\ 
     }\ 
    }; 


template <class T> 
struct TypeRegger { 
    static const int s_sideEffect; 
}; 

template <class T> 
const int TypeRegger<T>::s_sideEffect = T::registerType();