如果我想拥有一个与宏具有相同功能的函数,即在编译时计算值,我可以使用constexpr函数吗?
例如,我是否可以用foo函数替换Foo宏,并且在以下所有情况下仍然可以获得编译时评估的结果:
#define FOO(x) (x + 2)
constexpr int foo(int x) {
return x + 2;
}
void doSomething(int a) { ... }
int main() {
int res1 = foo(3);
doSomething(foo(4));
const int res2 = foo(5);
return 0;
}
答案 0 :(得分:4)
对于C ++ 20,consteval在这里可能是您的朋友:
consteval int foo(int x) {
return x + 2;
}
int main() {
constexpr int r = foo(2);
}
答案 1 :(得分:3)
就自己而言,constexpr
函数不需要在编译时进行评估。但是,您可以通过将返回值分配给constexpr变量来强制对它们进行求值:
doSomething(foo(4)); // foo(4) not guaranteed to be evaluated at compile time
constexpr auto result = foo(4); // foo(4) _is_ guaranteed to be evaluated at compile time
doSomething(result):
此外,请注意有关宏的问题。宏定义与编译时间评估无关。它更类似于始终内联的函数。
答案 2 :(得分:3)
无法检测是在运行时还是在编译时仅使用C ++本身对某些内容进行了评估,因此as-if rule允许编译器执行所需的操作。
什么都不会阻止编译器在运行时在宏中执行加法运算,也不会阻止编译器在编译时计算非constexpr
函数(只要它不执行任何IO等)。 )。这完全取决于优化设置和编译器的健全性。
通常,在未优化的构建中,constexpr
函数在运行时执行,除非在需要编译时常量的上下文中使用返回值。这包括从中初始化一个constexpr
变量,并且您的const int res2
隐式变为constexpr
,因为其初始值设定项是constexpr
,因此foo(5)
应该在编译时调用
在优化的构建中,可以期望编译器在编译时尽可能多地执行。 (只要功能主体在当前翻译单元中可见,或者启用了链接时优化,功能甚至都没有constexpr
。)