【问题标题】:What does it mean to be known at compile time? Constant expressions在编译时知道是什么意思?常量表达式
【发布时间】:2019-03-14 19:44:06
【问题描述】:

我对在编译时知道意味着什么感到困惑。从下面的代码中,即使我传递了一个常量字面值 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);
}

使用同样的逻辑,factorials(int i) 不应该给出错误,因为它不知道将要传递什么参数,因此编译器将无法计算将要返回的内容?

constexpr int factorials(int i) { 
    return i > 1 ? i * factorials(i - 1) : 1; 
    }

【问题讨论】:

    标签: c++ c++11 constants constexpr


    【解决方案1】:

    constexpr 关键字可能会造成混淆。它可以应用于变量和函数,但含义完全不同,只是它们都与常量表达式有关。

    使用constexpr 声明的变量必须由常量表达式初始化。在您的代码中,n + 7 不是常量表达式,因为在调用函数之前,n 的值是未知的,并且可能因一次调用而异。如果用户输入了某个整数,然后您将该整数传递给foo,该怎么办?显然,这个数字加 7 不是你可以称之为“编译时已知”的东西。因此,不允许使用诸如 foo 之类的函数定义。你不能向编译器保证你只会传递一个常量表达式参数。如果可以,则将n 提升为模板参数,代码将起作用。

    相比之下,constexpr 应用于函数并不能保证调用该函数会产生一个常量表达式。它允许在常量表达式中调用函数,并在定义上放置约束以使其成为可能。虽然factorial 如果给定一个运行时参数肯定不会产生一个常量表达式,但如果给定一个整数常量表达式作为参数(假设没有溢出),它将产生一个常量表达式。因此,与 constexpr 变量的初始化器不同,constexpr 函数允许包含可能具有或可能不具有编译时常量值的构造。

    【讨论】:

      猜你喜欢
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2013-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多