简体   繁体   中英

Can we omit const on local variables in constexpr functions?

For example:

constexpr int g() { return 30; }    

constexpr int f()
{
    // Can we omit const?
    const int x = g();
    const int y = 10;

    return x + y;
}

Is there any point to ever declare local variables in a constexpr function with const ?

Aren't constexpr functions with const local variables equivalent to those with no const ?

In other words, does constexpr on a function impose (imply) const on its local variables?

The same arguments for declaring variables as const in non- constexpr functions also apply to constexpr functions:

  • Declaring a variable const documents the fact that it won't ever be changed. This may in some instances help make the function more readable.
  • Declaring a variable const affects overload resolution, and may make h(x) resolve h differently depending on whether x is const .

Of course, in the opposite direction, as mentioned in comments already:

Even in constexpr functions, local variables may be changed. If those variables are then changed so that they are const , attempts to change them will no longer be accepted.

In this particular example the local variables would be best declared constexpr , not const , because they can be computed at compile time:

constexpr int g() { return 30; }    

constexpr int f()
{
    constexpr int x = g();
    constexpr int y = 10;

    return x + y;
}

When f() is called at run time, without the constexpr on x and y , (with or without the const on x and y ) you are giving the compiler the option to initialize x and y at run time instead of compile time. With the constexpr on x and y , the compiler shall compute x and y at compile time, even when f() is executed at run time.

In a different function however, constexpr can't always be used. For example if f() and g() took a parameter:

constexpr int g(int z) { return z+30; }    

constexpr int f(int z)
{
    const int x = g(z);
    constexpr int y = 10;

    return x + y;
}

Now x can not be marked constexpr because z may not be a compile-time constant, and there is currently no way to mark it as such. So in this case, marking x const is the best you can do.

You not only can , but sometimes you must ( ie if the variable changes), eg :

constexpr size_t f(size_t n) {
    size_t val = 1;
    if (n == 0) val++;
    return val;
}
char arr0[f(0)] = {'a', 'x'};
char arr1[f(1)] = {'y'};

is fine in C++14.

In general, a function can't be evaluated at compile time and therefore can't be called in a constant expression. Specifying a function as constexpr indicates that it can be used in constant expressions IF its input arguments are constants. For example this...

constexpr int n = func(7);

... must be evaluated at compile time.

That's the meaning of constexpr before functions. This being the case, it doesn't follow that the local variables inside the function don't have to be specified const.

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