因此,从C++14开始,constexpr在C++11中的限制就消失了,比如在constexpr函数中有新的变量或循环。
GCC和Clang编译器的最新版本已经支持它们。
所以问题是..。constexpr函数是在编译期间计算的,而不是在执行期间计算的,只要作为参数传递给它的值是常量。因此,我在下面编写的函数的结果应该在执行过程中立即出现,对吗?但事实并非如此。
我的问题是:为什么会发生这种事?我对C++14的constexpr特性有错误的理解吗?谢谢。
编辑:是的,我在使用-OO,这就是它不能工作的原因。但是设置-O1或更高的速度优化是可行的,程序按预期执行。谢谢大家的回答。
#include <iostream>
#include <chrono>
constexpr long long addition(long long num)
{
long long sum = 0;
for (int i = 0; i <= num; i++)
{
sum += i;
}
return sum;
}
int main()
{
auto start = std::chrono::steady_clock::now();
//////////////////////////////////////////////
std::cout << addition(500000000); //500 mill //executes in 1.957 seconds
///////////////////////////////////////////////
auto stop = std::chrono::steady_clock::now();
auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
std::cout << "\n\nIt took " << static_cast<double>(dur.count()) / 1000 << " seconds!";
std::cin.get();
}发布于 2015-09-16 04:02:40
如果将作为参数传递给它的值是常量,则在编译期间而不是在执行过程中计算一个constexpr函数。
不,编译器可以随意选择,就像使用“纯”函数而不是constexpr一样。除非您在需要编译时常量的上下文中使用它,例如初始化一个constexpr变量,或者在数组绑定中使用(不过要小心VLA g++扩展),或者作为一个非类型的模板参数使用。对于这些情况,需要编译时评估。(这并不是一个详尽的列表:还有其他需要编译时间常数的上下文,如开关case标签,但是如何将case标签值发送到cout?)
发布于 2015-09-22 10:57:51
为了补充@Ben Voigt的答案,下面是一个立即运行的实际工作示例:
#include <iostream>
#include <chrono>
constexpr long long addition(long long num)
{
long long sum = 0;
for (int i = 0; i <= num; i++)
{
sum += i;
}
return sum;
}
int main()
{
auto start = std::chrono::steady_clock::now();
//////////////////////////////////////////////
constexpr auto res = addition(500000);
std::cout << res; //500 mill //executes in 0 seconds
///////////////////////////////////////////////
auto stop = std::chrono::steady_clock::now();
auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
std::cout << "\n\nIt took " << static_cast<double>(dur.count()) / 1000 << " seconds!";
std::cin.get();
}Live Example。请注意,我必须从您的输入大小刮掉几个0。您可以使用-fconstexpr-steps=N编译器选项(对于Clang)来调整这一点。
https://stackoverflow.com/questions/32599545
复制相似问题