代码之家  ›  专栏  ›  技术社区  ›  IssamTP

constexpr成员函数给出C2131[重复]

  •  -1
  • IssamTP  · 技术社区  · 1 年前

    我已经理解了 const constexpr 和他们的应用程序,但我无法得到它的以下错误:

    // .hpp file
    class MyClass {
    public:
        constexpr double Square(double toBeSquared);
        static constexpr double Cube(double x);
        double ProcessRoutine();
    };
    
    // .cpp file
    constexpr double alternative_square_routine(double x)
    {
        return x * x;
    }
    
    double MyClass::Square(double toBeSquared)
    {
        return x * x;
    }
    
    double MyClass::Cube(double x)
    {
        return x * x * x;
    }
    
    double MyClass::ProcessRoutine()
    {
        // C2131: expression did not evaluate to a constant
        constexpr double square_const = Square(10.0);
        // This is fine:
        const double another_square = Square(5.0);
        // This is also fine:
        constexpr double another_square_again = alternative_square_routine(5.0);
        // Even this is fine:
        constexpr double cube = Cube(3.0);
    }
    

    MSVC告诉我,这涉及到 this 指针,在尝试Codiva.io中的代码时(我猜它使用GCC)会给出以下输出:

    error: constexpr variable 'square_const' must be initialized by a constant expression
    

    问题出在哪里?

    1 回复  |  直到 1 年前
        1
  •  0
  •   user17732522    1 年前

    const 只是意味着变量一旦初始化,就不应该是可修改的。对于运行时的任何其他变量,初始化都将正常进行。

    constexpr 要强大得多,并且另外强制初始化是 常量表达式 ,即在编译声明时可以在编译时对其进行评估,以便编译器可以仅用结果值替换初始化。

    什么表达式符合常量表达式的规则非常具体,例如。 here at cppreference

    之前 P2280 this 只有在作为常量表达式的一部分进行计算的constexpr函数内部使用时,才能在常量表达式计算中进行计算。

    constexpr double square_const = Square(10.0);
    

    是的缩写

    constexpr double square_const = this->Square(10.0);
    

    因为 Square 是一个非静态成员函数。你在这里评估 作为初始化的一部分 square_const 你想成为一个常量表达式(因为 常量表达式 ),而不是在 常量表达式 函数作为该常量表达式求值的一部分进行求值。

    P2280已被接受用于C++23,并作为针对C++11至C++20的缺陷报告。有了它,使用 只要你不试图访问的值,这里就会被允许 *this 。由于这是最近的缺陷报告,编译器可能还没有实现它。上面的cppreference链接还没有更新。

    只有 const 而不是 常量表达式 不需要任何常量表达式求值,因此它没有失败的原因。

    alternative_square_routine Cube 都很好,因为没有 卷入的这些不是非静态成员函数。