Reputation: 51
I am learning constexpr
and, for my understanding, constexpr
tells the compiler to calculate functions during compile time instead of running time. I used the following code for testing but bumped into an error I really don't understand. Can you please explain why?
#include <iostream>
#include <array>
using namespace std;
constexpr int foo(int i)
{
return i + 5;
}
int main()
{
int i = 10;
std::array<int, foo(5)> arr; // OK
// But...
std::array<int, foo(i)> arr1; // Error
}
The error is: the value of 'i
' is not usable in a constant expression. Why? i
is declared beforehand why does it have to be a const
?
Upvotes: 0
Views: 1050
Reputation: 66230
for my understanding constexpr tells the compiler to calculate functions during compile time instead of running time.
Not exactly: with constexpr
the compiler can (not must) calculate function compile time. And the compiler do it when it's necessary and possible.
In case of
std::array<int, foo(5)> arr; // OK
it's necessary (because the second template argument of std::array
must be known at compile time) and possible (because 5 is known at compile time).
But with
int i = 10;
std::array<int, foo(i)> arr1; // Error
it's necessary (std::array
) but not possible (because i
is a not-constant variable and the compiler can't use the i
value compile time but only run time).
It's necessary but not possible, so the error.
But you can write
int i { 10 };
int j { foo(i) };
because it's not possible call foo(i)
compile time but it isn't necessary (because j
can be initialized run time). So foo(i)
is called (supposedly) run time.
To compile the std::array
using foo(i)
, you should define i
as constexpr
(or const
)
constexpr int i { 10 };
so the compiler can use the value of i
compile time.
Why? i is declared beforehand why does it have to be a const?
Short answer: because the C++11 standard say so.
Long answer: because, in this way, it's simpler to construct a compiler. If you want to use a value compile time, you can declare it as constexpr
and the compiler check that it is never modified. It's (relatively) simple to do.
Otherwise, if you could use compile time the value of a not-constant variable, the compiler should follow the story of a variable to determine it's value when used in a constexpr
function. In your toy example is simple, in real life would be a nightmare.
Upvotes: 6