在此示例中如何理解constexpr?

时间:2019-04-02 09:08:31

标签: c++ c++17

我试图理解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只是对编译器的提示,例如“ inline”,它可以自由忽略?

3 个答案:

答案 0 :(得分:7)

  

我希望编译器会错误地认为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上查看此功能。该提案已被批准用于下一个标准。

答案 1 :(得分:2)

var bannerImage = [[String:AnyObject]]() var fileIDSArr = [String]() // these are how many images you want to load for i in 0..<fileIDSArr.count { let imageId:String = fileIDSArr[i] bannerImage.append([ "name":"Watch" as AnyObject, "name_of_owner": "Selena Gomez" as AnyObject, "phone_of_owner": "091237462" as AnyObject, "email_of_owner": "selenagomez@gmail.com" as AnyObject, "quantity":1 as AnyObject, "is_owned": false as AnyObject, "photo":"image data here..." as AnyObject]) } var params = [String:Any]() params = ["user_email":"johndoe@yopmail.com", "user_token":"yiDmaVs6Ax-zUj1cM-Eh", "claim_id": 6, "items":bannerImage] 关键字表示如果在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,因此它的初始化程序需要在编译时进行评估。因此出现错误。
如果没有此功能,则必须编写函数的两个版本,一个版本用于编译时使用,另一个版本用于运行时。
Compiler Explorer上亲自查看。

还请注意,constexpr暗示函数constexpr

答案 2 :(得分:0)

这就是我的观点

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)];