Search code examples
c++constexprc++20static-assertif-constexpr

How to cause static error in constexpr if-else chain?


In the following C++20 function template:

template<int i>
void f() {
    if constexpr (i == 1)
       g();
    else if constexpr (i == 2)
       h();
    else
       ??? // <--error
}

Is there something we can write in ??? such that a call of f<3>() will fail at compile-time?


Solution

  • The problem is that the discarded statement of constexpr if can't be ill-formed for every possible specialization. [temp.res.general]/6

    (emphasis mine)

    The validity of a template may be checked prior to any instantiation.

    The program is ill-formed, no diagnostic required, if:

    • no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or

    You can use a type-dependent expression that is always false. E.g.

    template<int i> struct dependent_false : std::false_type {};
    
    template<int i>
    void f() {
        if constexpr (i == 1)
           g();
        else if constexpr (i == 2)
           h();
        else
           static_assert(dependent_false<i>::value, "Must be 1 or 2");
    }