I have implemented a constexpr
compile-time hash-function, which works fine (i.e. is evaluated at compile-time) if called as
constexpr auto hash = CompileTimeHash( "aha" );
but I need to use it in actual code as an argument to a function as in
foo( CompileTimeHash( "aha" ) ); // foo is NOT constexpr
For a specific reason, I cannot use the long version
constexpr auto hash = CompileTimeHash( "aha" );
foo( hash );
The compiler (VC++) will not compile-time hash in the short (first) case.
Is there any way to achieve this?
EDIT: An example covering the 3 cases is now found here:
https://godbolt.org/z/JGAyuE
Only gcc gets it done in all 3 cases
Well, the as-if-rule always allows evaluation at runtime. However insane (and insanely complex) doing so might be.
Best shot to force your compiler to do it at compile-time, pass it through a template-argument:
A bit of setup:
template <auto x>
using make_integral_constant = std::integral_constant<decltype(x), x>;
template <auto x>
inline constexpr auto want_static = make_integral_constant<x>::value;
And use it like:
foo( want_static<CompileTimeHash( "aha" )> );
It works even without optimization, because unless you use an interpreter, doing it at runtime instead is too complex to do for no good reason.
Assigning to a constexpr
-variable should also work. But it is actually easier to not evaluate at compile-time, so without optimization that happens anyway.
foo( []{ constexpr auto r = CompileTimeHash( "aha" ); return r; }() );
If I understand correctly, your CompileTimeHash()
return a int
.
So what about
foo( sizeof(char[CompileTimeHash( "aha" )]) );
?
If CompileTimeHash()
return only positive numbers, obviously.
If CompileTimeHash()
return non negative numbers (positive numbers or zero), you can solve the zero problem (not acceptable as size for a C-style array) adding (inside) and subtracting (outside) 1
I mean
foo( sizeof(char[CompileTimeHash( "aha" )+1])-1u );