如何理解这个例子中的constexpr

How to understand constexpr in this example?

本文关键字:constexpr 何理解      更新时间:2023-10-16

我试图理解constexpr应用于函数时的含义。在下面的示例中,程序编译并运行,但我不明白如何在编译时推导出函数 sum(int n(,因为 n 直到运行时才知道。我正在使用带有最新更新的VS 2017。

该程序编译是否包含 constexpr。

#include <iostream>
constexpr int sum(int n)
{    
    return (n <= 0) ? 0 : n + sum(n-1);
}
int main()
{
    int i;
    std::cin >> i;
    std::cout << sum(i) << std::endl;
    return 0;
}

我希望编译器错误地认为 sum(int n( 不是一个常量表达式。或者constepxr只是对编译器的提示,比如"内联",它可以自由忽略?

我希望编译器错误地认为 sum(int n( 不是一个常量表达式。

constexpr int sum(int n);意味着可以在编译时计算函数。不必如此。您可以在运行时毫无问题地调用它,当程序员在运行时和编译时需要相同的功能时,不要强制程序员复制代码是有意义的。

使用 C++20,您将能够通过使用新关键字 consteval 而不是 constexpr 来限定函数来触发您预期的错误。

consteval int sum(int n)
{
    // As before...
}
int i;
// determine i at runtime...
sum(i); // Error! Not evaluated at compile time.

您可以查看 P1073 以了解此功能。该提案已获批准用于下一个标准。

constexpr 关键字表示如果在constexpr上下文中调用该函数,则必须在编译时计算该函数。

考虑:

constexpr int sum(int n)
{    
    return (n <= 0) ? 0 : n + sum(n-1);
}
int main()
{
    int i;
    std::cin >> i;
    constexpr int s1 = sum(4);        // OK, evaluated at compile time
    int s2 = sum(i);                  // OK, evaluated at run time
    constexpr int s3 = sum(i);        // Error, i cannot be evaluated at compile time
    int s4 = sum(4);                  // OK, execution time depends on the compiler's mood
}

在这里,s3 constexpr,因此需要在编译时评估它的初始值设定项。因此错误。
如果没有此功能,则必须编写函数的两个版本,一个用于编译时使用,另一个用于运行时使用。
在编译器资源管理器上自行查看。

另请注意,constexpr 意味着函数的inline

这是我的观点

constexpr, ensures that the constant must be a compile-time constant

因此

constexpr double pi (3.5); // is Okay because resolution is at compile time

而这个

// Should be Okay be cause the resolution of **sum** is at compiletime
// evaluation however is run-time dependent
constexpr int sum(int n)
{
    return (n <= 0) ? 0 : n + sum(n-1);
}

另一个例子是这样的

constexpr int compute(int x) { 
  return x+1; 
} 
int foo[compute(15)];