论证consteval
函数是:
-
sort of 编译时已知
- but is not 常量表达式
安德鲁·萨顿(Andrew Sutton)在他的论文中解释了这种行为背后的动机翻译和评估:编译时元编程的思维模型 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0992r0.pdf,如所指出的这个帖子 https://stackoverflow.com/a/57226813/2085626.
您可以从 a 返回参数consteval
函数并将其用作constexpr
:
consteval int foo(int n) {
return n;
}
constexpr int i = foo(9);
但你不能用它作为constexpr
在 - 的里面consteval
函数本身:
// fails to compile
consteval int abs(int n) {
if constexpr (n < 0) {
return -n;
}
else {
return n;
}
}
上面无法编译,如n is not a constexpr
.
您当然可以使用一个简单的 if,它将在编译时进行评估:
// compiles
consteval int abs(int n) {
if (n < 0) {
return -n;
}
else {
return n;
}
}
constexpr int i = -9;
constexpr int num = abs(i);
这是一个术语问题:
有没有一个常用的名字编译时已知, but 不是一个常量表达式?
TL;DR:不,C++ 标准中没有这样的术语。
就标准而言,“编译时已知”并不是一回事。有“常量表达式”的概念,也有“常量求值”的概念。
constexpr 函数(用以下方式声明的函数constexpr
or consteval
) 可以在常量表达式上下文中调用。常量表达式上下文是语言运行的地方requires表达式为常量表达式。模板参数、初始化器constexpr/constinit
变量等是常量表达式上下文。
当在常量表达式上下文中调用 constexpr 函数时,它们会生成常量表达式...或者您没有正确构造函数/参数并收到编译错误。就标准而言,差不多就是这样。
哦,是的,有关于 constexpr 函数的规则。他们被禁止执行某些 C++ 操作。并且有从常量表达式上下文调用它们的规则。但除此之外,就是这样。
您所指的区别仅仅是 constexpr 函数中允许的结果。您可以返回 constexpr 函数的参数,因为 constexpr 函数的返回值在语法上不是常量表达式。在适当的情况下,该功能可以进行不断的评估,但这就是标准需要说明的关于该主题的所有内容。
参数itself对于 C++ 来说并不特殊。特殊之处在于函数的定义是什么(即:你的函数是符合 constexpr 规则有效 https://timsong-cpp.github.io/cppwp/dcl.constexpr#3,这个评估是否做非constexpr事物 https://timsong-cpp.github.io/cppwp/expr.const#5),如何调用函数(即:您是否在常量表达式上下文中调用它),以及如何填充参数(即:参数是否为常量表达式)。
根据标准,有些表达式是常量表达式,有些表达式不是。但是,其值是通过常量表达式求值生成的,但本身不是语言常量表达式的表达式并不是标准的概念needs界定。它们只是价值观;它们是否处于常量表达式求值中与程序的行为并不真正相关。
所以这些东西没有名字。
立即函数(用以下函数声明的函数)consteval
) 只是一个 constexpr 函数,其中包含一些额外的规则。这些规则阻止你泄漏立即函数的地址 https://timsong-cpp.github.io/cppwp/expr.const#11.2(即:编译器不必为它们生成真正的函数)。标准规定调用立即函数is always常量表达式上下文 https://timsong-cpp.github.io/cppwp/expr.const#14(因此必须根据这些规则调用)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)