【问题标题】:The value of a const variable is or is not usable in a constant expression, depending on the variable typeconst 变量的值在常量表达式中是否可用,取决于变量类型
【发布时间】:2018-01-17 11:35:32
【问题描述】:

下面的代码没问题:

constexpr double square_cstxpr(double x) { return x * x; }

int main() {
    const int test = 5;
    constexpr double result = square_cstxpr((double)test);
}

但是,如果 test 的类型从 const int 更改为 const double,g++ 会给出以下错误:the value of 'test' is not usable in a constant expression

在此处查看 g++ 的代码和输出:http://coliru.stacked-crooked.com/a/2fe9b176c2b23798

有人能解释一下这种行为吗?

【问题讨论】:

  • 请添加不能编译的代码而不是描述它。
  • @molbdnilo 有一个指向 coliru 的链接。
  • 适合我!
  • 事实上,令我困惑的是工作案例场景。使用非constexpr 参数调用constexpr 函数应该是非法的,但由于某种原因,当参数的类型为const int 时,g++ 很高兴:/。
  • @YSC 这是合法的,例如参见 A Tour of C++ (by Bjarne Stroustrup),第 1.7 节。

标签: c++ c++11 constants constexpr


【解决方案1】:

constexprconst 变量必须是整数或枚举类型才能在常量表达式中使用。见[expr.const]/2

一个左值到右值的转换,除非它被应用到

(2.7.1) 整数或枚举类型的非易失性左值 它指的是一个完整的非易失性 const 对象,前面有一个 初始化,用常量表达式初始化,或 [..]

造成这种限制的原因主要是历史原因。当涉及到常量表达式时,浮点数已经被小心处理了;考虑非类型模板参数。这是由于它们强烈依赖于平台的行为导致编译时计算的数学性低于应有的程度。

【讨论】:

  • 几年前,CWG 拒绝了 EWG 将 const float 用于常量表达式 IIRC 的请求。
  • @T.C. y CWG 这样做是为了让每个人都过得很辛苦~?
【解决方案2】:

来自constant expression(核心常量表达式):

10) 任何其他左值到右值的隐式转换,除非 左值...

a) 具有整数或枚举类型,指的是一个完整的非易失性 const对象,用常量表达式初始化

意思是:

const int test1 = 5;
constexpr double result1 = square_cstxpr((double)test1);

test1 是一个常量表达式,square_cstxpr 可以在编译时以test1 作为参数调用,其结果可以赋值给constexpr 变量 result

另一方面,这里:

const double test2 = 5;
constexpr double result2 = square_cstxpr((double)test2);

test2 不是常量表达式,因为它不是整数或枚举类型。因此,square_cstxpr 不能在编译时以 test2 作为参数调用。

【讨论】:

  • 你能评论一下为什么const doubleconst float 除了 Columbo 的最后一条语句之外不允许在常量表达式中使用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多