简体   繁体   中英

Compile Error: Use constexpr to declare std::array size

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 ?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM