2017-04-06 1 views
0

Je souhaite initialiser un membre struct avec un hachage du nom de la structure.Fonction Constexpr dans la liste d'initialisation du constructeur 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; 
} 

Quand j'ai:

constexpr My_Struct my_constexpr_struct; 

Ensuite, le hachage est calculé au moment de la compilation avec succès. Cependant, quand j'ai dans ma fonction principale

My_Struct my_normal_struct; 

il appellera le

constexpr uint32_t myHash(const char* const data) 
fonction

dans le code au lieu de initialisant simplement le membre struct avec une constante de compilation.

Ceci entraînerait évidemment une pénalité de performance significative qui est évitable.

Des pensées ou des suggestions sur la façon dont le compilateur effectuer cela au moment de la compilation? Je ne veux pas vraiment faire:

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

Merci.

Répondre

2

constexpr est une demande, pas une exigence. En tant que tel, si vous initialisez un objet en dehors d'un contexte d'expression constante, même à travers un constructeur constexpr, il n'y a aucune garantie que l'initialisation sera effectuée au moment de la compilation.

Si vous souhaitez garantir une évaluation à la compilation, vous avez pour appeler la fonction constexpr dans un contexte d'expression constante. Si l'utilisation explicite d'une variable vous offense d'une certaine façon, vous pouvez toujours forcer l'évaluation constexpr par l'utilisation d'un modèle:

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

Merci, cette (ou une variante de cela) pourrait fonctionner. – Flip