我对在编译时知道它的含义感到困惑。从下面的代码中,即使我已将常量文字值90作为参数传递,编译器是否也无法计算n
的值?为什么给我一个错误,就是表达式必须具有常数值
constexpr int MAX_expr = 100;
const int MAX = 90;
void foo(int n)
{
constexpr int cExpr1 = MAX_expr + 7;
constexpr int cExpr2 = n + 7;
constexpr int cExpr1 = MAX + 7;
constexpr int cExpr2 = n + 7;
const int cExpr1 = MAX_expr + 7;
const int cExpr2 = n + 7;
const int cExpr1 = MAX + 7;
const int cExpr2 = n + 7;
}
int main() {
foo(90);
const int i = factorials(90);
}
使用相同的逻辑,阶乘(int i)是否不应给出错误,因为它不知道将传递什么参数,因此,编译器将无法计算将要返回的内容? / p>
constexpr int factorials(int i) {
return i > 1 ? i * factorials(i - 1) : 1;
}
答案 0 :(得分:3)
constexpr
关键字可能令人困惑。它可以应用于变量和函数,但是含义完全不同,除了它们都与常量表达式有关。
用constexpr
声明的变量必须由常量表达式初始化。在您的代码中,n + 7
不是常数表达式,因为n
的值直到函数被调用之前才知道,并且每次调用之间可能有所不同。如果用户输入了某个整数,然后又将该整数传递给foo
,该怎么办?显然,该数字加7不能称为“编译时已知”。因此,不允许使用诸如foo
之类的函数定义。您不能向编译器保证只能传递一个常量表达式参数。如果可以的话,然后将n
提升为模板参数,代码将起作用。
相反,应用于函数的constexpr
不能保证调用该函数会产生一个常量表达式。它允许在常量表达式中调用该函数,并在定义上施加约束以使其成为可能。如果给定一个运行时参数,factorial
当然不会产生一个常数表达式,但是如果给定一个整数常数表达式作为参数,它将产生一个常数表达式(假设没有溢出)。因此,与constexpr
变量的初始化程序不同,constexpr
函数被允许包含可能具有或可能不具有编译时常数值的构造。