Constexpr是正确的行为吗?

时间:2015-10-22 18:25:28

标签: c++ constants constexpr

我不确定这是正确的行为。所以我以前没有搞过constexpr,并且想确保我不会误解有关规范的内容。以MSDN提到的测试方式进行测试。如果我在函数中放置一个断点并且它被跳过,那么它在编译时被评估。行为是否低于正常水平?

https://msdn.microsoft.com/en-us/library/dn956974.aspx

  1. 它似乎只适用于期间的优化。
  2. 仅当我将值设置为constexpr变量或在输入变量没有任何关系的特定用例时才有效。
  3. 因此出于某种原因,这是有效的

    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在合规方面遇到了一些问题,但是基于用例而不是根据用例评估常量的行为而不是输入是不变的,这对我来说似乎很奇怪。

1 个答案:

答案 0 :(得分:0)

您观察到的行为是正确的。只需在常量表达式上在编译时调用constexpr函数。这包括将constexpr函数的返回值用作constexpr变量的初始值设定项或非类型模板参数的值的情况。

在所有其他情况下,编译器不需要在编译时评估该函数。