I am trying to write a function such that if called with compile-time-constant arguments it will trigger a compile-time error if the value of the argument doesn't match a static_assert
, but can still be called at run-time with computed values.
Something kinda like this:
template<int N> void f(N){
static_assert(N == 5, "N can only be 5.");
do_something_with(N);
}
void f(int N){
if(N == 5){
do_something_with(N);
}
}
volatile int five = 5;
volatile int six = 6;
int main() {
f(5); //ok
f(6); //compile-time error
f(five); //ok
f(six); //run-time abort
return 0;
}
How can I do this?
Also, if possible I would like to be able to keep the simple f(something)
syntax, because this code is intended for a library that should be usable by beginner programmers that aren't familiar with template syntax.
The best I can imagine is a constexpr
function that throw an exception.
If executed at compile time, the throw
cause a compilation error; if executed at run time, throw the exception
Someting like
#include <stdexcept>
constexpr int checkGreaterThanZero (int val)
{ return val > 0 ? val : throw std::domain_error("!"); }
int main()
{
// constexpr int ic { checkGreaterThanZero(-1) }; // compile error
int ir { checkGreaterThanZero(-1) }; // runtime error
}
-- EDIT --
As pointed by yuri kilocheck, instead of throwing an exception, you can call std::abort()
; by example
constexpr int checkGreaterThanZero (int val)
{ return val > 0 ? val : (std::abort(), 0); }