我试图理解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”,它可以自由忽略?
答案 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)];