I'm trying to compare a function parameter inside a constexpr-if statement.
Here is a simple example:
constexpr bool test_int(const int i) {
if constexpr(i == 5) { return true; }
else { return false; }
}
However, when I compile this with GCC 7 with the following flags:
g++-7 -std=c++1z test.cpp -o test
I get the following error message:
test.cpp: In function 'constexpr bool test_int(int)':
test.cpp:3:21: error: 'i' is not a constant expression
if constexpr(i == 5) { return true; }
However, if I replace test_int
with a different function:
constexpr bool test_int_no_if(const int i) { return (i == 5); }
Then the following code compiles with no errors:
int main() {
constexpr int i = 5;
static_assert(test_int_no_if(i));
return 0;
}
I don't understand why the constexpr-if version fails to compile, especially since the static_assert works just fine.
Any advice on this would be appreciated.
Thanks!
A constexpr function can be called with non-constexpr arguments, in which case it behaves like a normal function, so the code must still compile as if it were not constexpr.
In short, there's nothing in test_int_no_if that depends on i being constexpr, while in test_int(), there is. ("constexpr if" only works with compile time expressions.)
From constexpr if:
Then, from constant expression:
Obviously,
i == 5
is not a constant expression, becausei
is a function parameter which is evaluated at run time. That is why the compiler complains.When you use a function:
then it might be evaluated during the compile time depending on whether it's parameter is known at compile time or not.
If
i
is defined like:then the value of
i
is known during the compile time andtest_int_no_if
might be evaluated during the compile too making it possible to call it insidestatic_assert
.Also note, that marking function parameter as
const
does not make it a compile time constant. It just means that you cannot change the parameter inside the function.