Search code examples
c++metaprogrammingconstexpr

Can't use if constexpr with a reference parameter to a constexpr function


My code below produces the following error:

C2131: expression did not evaluate to a constant.

    template<int32_t M, int32_t N>
    [[nodiscard]] constexpr double determinant(const Matrix<M,N> & m)
    {
        double det = 0;
        if constexpr(m.rows() == 2)
        {
            return m[0][0]*m[1][1] - m[0][1]*m[1][0];
        }
        else
        {
            for(std::size_t col = 0; col < m.cols(); ++col)
            {
                det += m[0][col] * cofactor(m, 0, col);
            }
        }
        return det;
    }

My "first" error with regular if statement was:

C1202: recursive type or function dependency context too complex.

Someone here on stackoverflow had a similar error while doing similar stuff, his solution was to use if constexpr because otherwise the if statement could not be evaluated at compile time. But this produces my current error C2131.

Matrix<M,N> has a method rows() which is also constexpr. Can someone explain to me why this code won't compile?


Solution

  • If Matrix<M, N> defines rows() to return M, just replace

    if constexpr (m.rows() == 2)
    

    with

    if constexpr (M == 2)
    

    m.rows() does not produce a constant expression even if rows() is marked as a constexpr because m is a reference. Here is an explanation why.