Search code examples
c++c++11templatesoverloadingstatic-assert

Generate compile-time error if compile-time-constant parameter is wrong


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.


Solution

  • 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); }