在这个例子中如何理解constexpr?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在这个例子中如何理解constexpr?相关的知识,希望对你有一定的参考价值。

我试图理解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
}

在这里,s3constexpr,所以它的初始化程序需要在编译时进行评估。因此错误。 如果没有此功能,则必须编写函数的两个版本,一个用于编译时使用,另一个用于运行时使用。 在Compiler Explorer上亲眼看看。 另请注意,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)];    

以上是关于在这个例子中如何理解constexpr?的主要内容,如果未能解决你的问题,请参考以下文章

Gcc 7.2 c++17 constexpr

constexpr 表达式和变量生存期,一个 g++ 和 clang 不一致的例子

c++11中的constexpr概念

如何创建片段以重复变量编号中的代码行

如何理解这段代码片段中的两对括号?

在这个 spark 代码片段中 ordering.by 是啥意思?