I would like to initialise a struct member with a hash of the struct name.
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;
}
When I have:
constexpr My_Struct my_constexpr_struct;
Then the hash is computed at compile time successfully. However, when I have in my main function
My_Struct my_normal_struct;
then it will call the
constexpr uint32_t myHash(const char* const data)
function in the code instead of simply initialising the struct member with a compile time constant.
This would obviously incur a significant performance penalty that is avoidable.
Any thoughts or suggestions on how to have the compiler perform this at compile time? I don't really want to do:
constexpr uint32_t MY_STRUCT_ID = myHash("My_Struct");
struct My_Struct{
constexpr Test() : ID(MY_STRUCT_ID)
{
}
const uint32_t ID;
Thanks.
constexpr
is a request, not a requirement. As such, if you initialize an object outside of a constant expression context, even through a constexpr
constructor, there is no guarantee that the initialization will be done at compile time.
If you want to guarantee compile-time evaluation, you have to call the constexpr
function it in a constant expression context. If the explicit use of a variable offends you in some way, you could always force constexpr
evaluation through the use of a template:
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;
};