Search code examples
c++language-lawyerconstexprc++20class-template

Will consteval functions allow template parameters dependent on function arguments?


In C++17, this code is illegal:

constexpr int foo(int i) {
    return std::integral_constant<int, i>::value;
}

That's because even if foo can be evaluated at compile-time, the compiler still needs to produce the instructions to execute it at runtime, thus making the template instantiation impossible.

In C++20 we will have consteval functions, which are required to be evaluated at compile-time, so the runtime constraint should be removed. Does it mean this code will be legal?

consteval int foo(int i) {
    return std::integral_constant<int, i>::value;
}

Solution

  • No.

    Whatever changes the paper will entail, which is little at this point, it cannot change the fact that a non-template function definition is only typed once. Moreover, if your proposed code would be legal, we could presumably find a way to declare a variable of type std::integral_constant<int, i>, which feels very prohibitive in terms of the ODR.

    The paper also indicates that parameters are not intended to be treated as core constant expressions in one of its examples;

    consteval int sqrsqr(int n) {
      return sqr(sqr(n)); // Not a constant-expression at this  point,
    }                     // but that's okay.
    
    

    In short, function parameters will never be constant expressions, due to possible typing discrepancy.