【问题标题】:constexpr function contains a const - will it ever be evaluated at compile time?constexpr 函数包含一个 const - 它会在编译时进行评估吗?
【发布时间】:2019-04-24 04:52:00
【问题描述】:

请有人澄清一下(我使用的是 Visual Studio 15.9.2):

在下面的代码中,假设 Pi_cnst 在运行时评估(因为以这种方式定义 Pi 需要运行时计算),RAD2DEG_cnst 是否会在编译时评估,或者使用“constexpr”总是恢复为“const “?

编辑 - 添加:如果它总是恢复为 const 那么我应该期待一个警告,还是以其他方式不好,即能够如此轻松地声明一个 constexpr 以使主体被接受但总是如此似乎很奇怪使其永远不是真正的 constexpr。我错过了什么?

constexpr double Pi_error = std::acos(-1.0); //error function call must have a constant value in a constant expression (does not compile)
const double Pi_cnst = std::acos(-1.0); //ok evaluated at run time

constexpr double Pi_expr = 3.1415926; //ok valid constexpr

constexpr double RAD2DEG_cnst(double rad) { return rad * 180.0 / Pi_cnst; } //no error or warning BUT is this ever evaluated at compile time?
constexpr double RAD2DEG_expr(double rad) { return rad * 180.0 / Pi_expr; } //ok can be evaluated at compile time

const double result1 = RAD2DEG_cnst(0.1); //evaluated at run time?
const double result2 = RAD2DEG_expr(0.2); //evaluated at compile time?

double myVariable = 0.3;
const double result3 = RAD2DEG_expr(myVariable); //ok - but can only be evaluated at run time

const double myOtherVariable = 0.4;
const double result4 = RAD2DEG_expr(myOtherVariable); //ok - evaluated at compile time because parameter is CONST?

我还发现了constexpr function and its parameterconstexpr vs const vs constexpr const

【问题讨论】:

  • 有什么问题?你看到acos在 constexpr 中不起作用。
  • @MatthieuBrucher: Pi_cnst 不能是 constexpr,因为 acosRAD2DEG_cnstconstexpr,尽管它依赖于 Pi_cnst。我认为问题是:如何在执行 unconstexprable 操作时将其声明为 constexpr,以及在实践中编译时评估意味着什么?
  • 哦,好的。我认为 constexpr 并不总是构建时间......
  • 我在使用 gcc9 时收到 RAD2DEG_cnst 的错误:“在函数 'constexpr double RAD2DEG_cnst(double)' 中:错误:'Pi_cnst' 的值在常量表达式中不可用”跨度>

标签: c++ constexpr


【解决方案1】:

您的代码格式错误,无需诊断。在

constexpr double RAD2DEG_cnst(double rad) { return rad * 180.0 / Pi_cnst; }

没有任何输入可以使函数成为core constant expression 指定的[dcl.constexpr]/5

对于既不是默认值也不是模板的 constexpr 函数或 constexpr 构造函数,如果不存在参数值,则函数或构造函数的调用可以是核心常量表达式的求值子表达式,或者,对于构造函数,某些对象([basic.start.static])的常量初始化程序,程序格式错误,不需要诊断。

【讨论】:

    猜你喜欢
    • 2012-12-24
    • 2017-05-26
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 2014-04-06
    • 2012-12-27
    相关资源
    最近更新 更多