Search code examples
c++if-constexpr

Stop compilation if `if constexpr` does not match


I have a template function that checks the type of a template argument with an if constexpr such as

template <typename T>
bool something(T arg) {
  if constexpr (std::is_integral_v<T>) {
    return true;
  } else {
    // What can I write here so that something<double>(0.0) does not compile?
  }

  return false;
}

How can I make the code fail to compile if none of my if constexprs match?


Solution

  • The soltuion is to use static_assert.

    But we can't simply do static_assert(false, "whatever"); in the else branch, because since the condition doesn't depend on the template parameter, assertion might fire early (when the compiler first sees your function body, even if the else branch is never actually taken).

    The condition of static_assert has to somehow depend on T, to delay the assertion check until your template is instantinated.

    This is what I've been using:

    template <auto A, typename...> auto value = A;
    
    if constexpr (foo)
    {
        ...
    }
    else if constexpr (bar)
    {
        ...
    }
    else
    {
        static_assert(value<false, T>, "Invalid template parameter.");
    }
    

    Note that if you only have one if constexpr (rather than an if else if chain), then none of that is needed.

    Simply move the condition from if to a static_assert and remove the if.