Can I detect at compile time whether "function arguments"1 are compile-time constants?
For example a function print(int i)
that can print "constant 5"
if called as print(5)
but "non-constant 5"
if called as print(i)
where i
is some non-constant variable. In particular, in the "is constant" branch I should be able to treat i
as a constexpr, including using it for template arguments, etc.
Macro tricks, template meta-programming and SFINAE tricks are all OK. Ideally it is portable, but solutions that are compiler-specific are better than nothing.
It's OK if there are "false negatives" - i.e., if constant values are sometimes detected as non-constant (e.g., when certain optimizations are disabled).
Bonus points if the solution can detect when constant values are indirectly passed to the function (e.g., when a constant value is passed to an intermediate function that calls print
and which is subsequently inlined exposing the constant to print
). This last behavior is evidently optimization dependent.
Double bonus points if it naturally extends to multiple arguments.
If one could have overloaded versions of functions with and without constexpr
arguments this would presumably be straightforward, but you can't.
1 I'm putting "function arguments" in quotes here because the solution doesn't strictly require detecting this state within a function (or at the caller/callee boundary with special arguments) - it just has to appear to the caller like a function but macros or other tricks like a static object with operator()
etc could be used.