2017-04-06 20 views
0

struct名をハッシュしてstructメンバーを初期化したいとします。constexprコンストラクタの初期化子リストのconstexpr関数

constexpr uint32_t myHash(const char* const data) 
{ //Some code for hash 
    return myHash; 
} 

struct My_Struct{ 
    constexpr Test() : ID(myHash("My_Struct")) 
    { 
    } 
    const uint32_t ID; 
} 

私が持っている場合:

constexpr My_Struct my_constexpr_struct; 

次にハッシュが正常にコンパイル時に計算されます。私は私の主な機能を持っているときしかし、

My_Struct my_normal_struct; 

が、それは単に、コンパイル時定数で構造体のメンバを初期化するのではなく、コード内

constexpr uint32_t myHash(const char* const data) 

関数を呼び出します。

これは明らかに回避できない大きなパフォーマンス上のペナルティを招きます。

コンパイラにコンパイル時にこれを実行させる方法に関する意見や提案はありますか?私は本当にやりたいとは思わない:

constexpr uint32_t MY_STRUCT_ID = myHash("My_Struct"); 
struct My_Struct{ 
    constexpr Test() : ID(MY_STRUCT_ID) 
    { 
    } 
    const uint32_t ID; 

ありがとう。

答えて

2

constexprは必須ではありません。そのため、定数式コンテキスト外のオブジェクトを初期化すると、たとえconstexprコンストラクタであっても、コンパイル時に初期化が行われるという保証はありません。

コンパイル時の評価を保証する場合は、となり、constexprを定数式コンテキストで機能させることができます。変数の明示的な使用は、いくつかの方法であなたを傷つける場合は、いつでも、テンプレートを使用してconstexpr評価を強制することができます:

template<typename T, T t> 
struct repeat 
{ 
    using value_type = T; 
    static constexpr T value = t; 
    constexpr T operator()() const noexcept {return t;} 
}; 

struct My_Struct{ 
    constexpr My_Struct() : ID(repeat<uint32_t, myHash("My_Struct")>::value) 
    { 
    } 
    const uint32_t ID; 
}; 
+0

おかげで、この(またはこれのいくつかのバリエーションが)仕事ができます。 – Flip

関連する問題