我不确定这是正确的行为。所以我以前没有搞过constexpr,并且想确保我不会误解有关规范的内容。以MSDN提到的测试方式进行测试。如果我在函数中放置一个断点并且它被跳过,那么它在编译时被评估。行为是否低于正常水平?
https://msdn.microsoft.com/en-us/library/dn956974.aspx
因此出于某种原因,这是有效的
constexpr unsigned int factorial(unsigned int n)
{
return n <= 1 ? 1 : n*factorial(n - 1);
}
constexpr unsigned int value = factorial(5);
std::cout << value << std::endl;
但这会在运行时运行
constexpr unsigned int factorial(unsigned int n)
{
return n <= 1 ? 1 : n*factorial(n - 1);
}
std::cout << factorial(5) << std::endl;
看起来有点不方便做一个constexpr变量。它似乎适用于其他一些特殊情况。
switch (fnv1a("Hello"))
{
case fnv1a("GoodBye"):
std::cout << "GoodBye" << std::endl;
break;
case fnv1a("Hello"):
std::cout << "Hello" << std::endl;
break;
default:
break;
}
这种情况将case值初始化为常量,但switch语句中的调用不会计算为constexpr并在运行时运行。
同样,平等运营商似乎也出于某种原因而工作。此示例仅为动态值调用fnv1a一次。
void isValue(const char* str)
{
if (fnv1a(str) == fnv1a("Hello"));
std::cout << "Found it!" << std::endl;
}
我知道MSVC在合规方面遇到了一些问题,但是基于用例而不是根据用例评估常量的行为而不是输入是不变的,这对我来说似乎很奇怪。
答案 0 :(得分:0)
您观察到的行为是正确的。只需在常量表达式上在编译时调用constexpr
函数。这包括将constexpr
函数的返回值用作constexpr
变量的初始值设定项或非类型模板参数的值的情况。
在所有其他情况下,编译器不需要在编译时评估该函数。