使用consteval而不是conexpr函数有什么好处?
我知道需求的不同,我最感兴趣的是它带来的代码质量带来的好处。
我能想到的几件事:
- 读者只需阅读函数签名即可知道该函数是在编译时计算的
- 编译器可能会发出较少的代码,因为
consteval
FN从不在运行时使用(这只是推测,我没有这方面的真实数据) - 不需要有变量来强制ctfe,最后的示例
注意:如果代码质量太模糊,我理解有些人可能想结束这个问题,对我来说,代码质量并不是那个模糊的术语,但...
example其中constexpr
故障延迟到运行时:
constexpr int div_cx(int a, int b)
{
assert(b!=0);
return a/b;
}
int main()
{
static constexpr int result = div_cx(5,0); // compile time error, div by 0
std::cout << result;
std::cout << div_cx(5,0) ; // runtime error :(
}
解决方案
为了有意义、有意义的静态反射(编译时的反射),您需要一种在编译时执行代码的方法。最初的静态反射TS方案使用传统的模板元编程技术,因为这些技术是在编译时执行代码的唯一有效工具。
然而,随着constexpr
代码获得更多功能,通过constexpr
函数进行编译时静态反射变得越来越可行。这种想法的一个问题是,不能允许静态反射值泄漏到非编译时代码中。
我们需要能够编写在编译时必须只执行的代码。对于函数中间的一小段代码,要做到这一点很容易;该代码的运行时版本不包含反射部分,只包含反射部分的结果。
但是,如果您想编写一个接受反射值并返回反射值的函数,该怎么办?或反射值列表?constexpr
函数不能为constexpr
,因为constexpr
函数必须能够在运行时执行。您可以执行如下操作:获取指向constexpr
函数的指针,并以编译器无法跟踪的方式调用它们,从而强制其在运行时执行。
接受反射值的函数不能做到这一点。它只能在编译时执行。因此constexpr
不适用于此类功能。
Enterconsteval
:"required" to execute only at compile time的函数。存在特定的规则,使得指向此类函数的指针不可能泄漏到运行时代码中,依此类推。
因此,consteval
目前没有多大用途。它在a few places like source_location::current()
,中使用,这在运行时执行根本没有意义。但归根结底,该功能是进一步编译时编程工具的必要构建块,而这些工具目前还不存在。
这是在paper that originally proposed this feature:
中规定的
然而,推动本论文的是SG7在编译时反射领域所做的工作。现在普遍认为,未来对反射的语言支持应使用constexpr
函数,但由于反射函数通常必须在编译时计算,因此它们实际上很可能是直接函数。
相关文章