我们可以在 constexpr 函数中省略局部变量的 const 吗?
Can we omit const on local variables in constexpr functions?
例如:
constexpr int g() { return 30; }
constexpr int f()
{
// Can we omit const?
const int x = g();
const int y = 10;
return x + y;
}
有没有任何意义 在 constexpr
函数中使用 const
声明局部变量?
带有 const
局部变量的 constexpr
函数 等同于 没有 const
的函数吗?
换句话说,constexpr
对函数 施加 (暗示)const
对其局部变量吗?
一般来说,函数无法在编译时求值,因此无法在常量表达式中调用。将函数指定为 constexpr 表示如果其输入参数是常量,则可以在常量表达式中使用它。例如这个...
constexpr int n = func(7);
...必须在编译时求值。
这就是函数前constexpr的意思。既然如此,并不意味着函数内部的局部变量不必指定为const。
在非constexpr
函数中将变量声明为const
的相同参数也适用于constexpr
函数:
- 声明一个变量
const
表明它永远不会被改变。在某些情况下,这可能有助于提高函数的可读性。
- 声明变量
const
会影响重载解析,并且可能会使 h(x)
以不同方式解析 h
,具体取决于 x
是否为 const
。
当然是相反的方向,正如评论中已经提到的:
即使在constexpr
函数中,局部变量也可能被改变。如果这些变量随后被更改为 const
,将不再接受更改它们的尝试。
在这个具体例子中,局部变量最好声明为constexpr
,而不是const
,因为它们可以[=48] =] 在编译时计算:
constexpr int g() { return 30; }
constexpr int f()
{
constexpr int x = g();
constexpr int y = 10;
return x + y;
}
当 f()
在 运行 时调用时,x
和 y
上没有 constexpr
,(有或没有 const
在 x
和 y
) 上,您为编译器提供了在 运行 时间而不是编译时间初始化 x
和 y
的选项。对于 x
和 y
上的 constexpr
,编译器 应 在编译时计算 x
和 y
,即使当f()
在运行时执行。
然而,在不同的功能中,constexpr
不能总是使用。例如,如果 f()
和 g()
有一个参数:
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;
}
现在无法将 x
标记为 constexpr
因为 z
可能不是编译时常量,目前无法将其标记为这样。所以在这种情况下,标记 x
const
是你能做的最好的。
你不仅可以,有时你必须(即如果变量改变), 例如:
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'};
在 C++14 中没问题。
例如:
constexpr int g() { return 30; }
constexpr int f()
{
// Can we omit const?
const int x = g();
const int y = 10;
return x + y;
}
有没有任何意义 在 constexpr
函数中使用 const
声明局部变量?
带有 const
局部变量的 constexpr
函数 等同于 没有 const
的函数吗?
换句话说,constexpr
对函数 施加 (暗示)const
对其局部变量吗?
一般来说,函数无法在编译时求值,因此无法在常量表达式中调用。将函数指定为 constexpr 表示如果其输入参数是常量,则可以在常量表达式中使用它。例如这个...
constexpr int n = func(7);
...必须在编译时求值。
这就是函数前constexpr的意思。既然如此,并不意味着函数内部的局部变量不必指定为const。
在非constexpr
函数中将变量声明为const
的相同参数也适用于constexpr
函数:
- 声明一个变量
const
表明它永远不会被改变。在某些情况下,这可能有助于提高函数的可读性。 - 声明变量
const
会影响重载解析,并且可能会使h(x)
以不同方式解析h
,具体取决于x
是否为const
。
当然是相反的方向,正如评论中已经提到的:
即使在constexpr
函数中,局部变量也可能被改变。如果这些变量随后被更改为 const
,将不再接受更改它们的尝试。
在这个具体例子中,局部变量最好声明为constexpr
,而不是const
,因为它们可以[=48] =] 在编译时计算:
constexpr int g() { return 30; }
constexpr int f()
{
constexpr int x = g();
constexpr int y = 10;
return x + y;
}
当 f()
在 运行 时调用时,x
和 y
上没有 constexpr
,(有或没有 const
在 x
和 y
) 上,您为编译器提供了在 运行 时间而不是编译时间初始化 x
和 y
的选项。对于 x
和 y
上的 constexpr
,编译器 应 在编译时计算 x
和 y
,即使当f()
在运行时执行。
然而,在不同的功能中,constexpr
不能总是使用。例如,如果 f()
和 g()
有一个参数:
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;
}
现在无法将 x
标记为 constexpr
因为 z
可能不是编译时常量,目前无法将其标记为这样。所以在这种情况下,标记 x
const
是你能做的最好的。
你不仅可以,有时你必须(即如果变量改变), 例如:
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'};
在 C++14 中没问题。