在C++20中,立即函数(immediate function)是指每次调用该函数都会直接或间接产生编译时常量表达式(constant expression)的函数。这些函数在其返回类型前使用consteval关键字进行声明。
立即函数是constexpr函数,具体情况取决于其要求。与constexpr相同,consteval说明符隐式内联(inline)。但是,它不能应用于析构函数、分配函数或释放函数(destructors, allocation functions, or deallocation functions)。
立即函数:
(1).它一定不是协程(coroutine)。
(2).其函数体内不能有throw语句。
(3).除了case和default之外,不能有goto语句或标签语句(label statement)。
(4).它的参数以及返回类型必须是常量类型(literal type),或者简而言之,可以是编译时可评估的类型(例如,所有可以在constexpr上下文中使用的类型)。
consteval说明符(specifier)指定某个函数为立即函数,即每次调用该函数都必须产生一个编译时常量。
consteval说明符将函数或函数模板声明为立即函数,也就是说,对该函数的每个潜在求值(potentially-evaluated)调用都必须(直接或间接)生成编译时常量表达式。
为了性能,必须在编译时运行的函数,请使用consteval。
constexpr与consteval:
(1).constexpr说明符声明可以在编译时(compile time)评估(evaluate)函数或变量的值。此类变量和函数可用于仅允许使用编译时常量表达式的地方。这些函数用于通过在编译时而不是运行时(compile time instead of run time)进行计算来提高程序的性能。当多次执行一个程序时,这些函数真的很有用,因为常量表达式在编译期间只会被评估一次。
(2).在consteval函数中,每次调用该函数都必须直接或间接地产生一个编译时常量表达式。consteval函数与constexpr函数相同,不同之处在于,如果对consteval 函数的调用没有计算出编译时常量表达式,则程序会出错,而constexpr函数则不会出错。constexpr指定变量或函数的值可以出现在常量表达式中,它说函数可以出现在常量表达式中,而不是说函数必须如此,而consteval指定函数是立即函数,也就是说,每次调用该函数都必须产生一个编译时常量。
(3).函数或模板函数声明时指定为了consteval就不能同时再指定为constexpr,并且该函数或模板函数的任何重新声明(redeclarations)也必须指定为consteval。
(4).类似于constexpr函数,但是带有consteval说明符的函数必须产生一个常量。这些被称为立即函数。
(5).consteval函数只能调用constexpr函数,而反之则不行。
(6).consteval:compile-time only;constexpr:compile-time or run-time
以下为测试代码:
namespace {
//constexpr int fib(int n) // ok
consteval int fib(int n)
{
if (n <= 1)
return n;
return fib(n - 1) + fib(n - 2);
}
consteval int f() { return 42; }
consteval auto g() { return &f; }
consteval int h(int (*p)() = g()) { return p(); }
constexpr int r = h();
} // namespace
int test_consteval()
{
constexpr int v{ 10 }; // note: difference between with constexpr and without constexpr
// int v{ 10 }; // constexpr int fib(int n): ok; consteval int fib(int n): error
constexpr int result = fib(v);
std::cout << "result: " << result << std::endl;
return 0;
}
执行结果如下图所示:
GitHub:https://github.com/fengbingchun/Messy_Test