【问题标题】:constexpr reference to non-const objectconstexpr 对非常量对象的引用
【发布时间】:2017-09-18 00:21:36
【问题描述】:

是否允许将非常量引用声明为constexpr?示例代码:

int x = 1;
constexpr int& r = x;

gcc 和 clang 都接受了这一点(我尝试了两者的当前和过去版本,回到 C++11,都接受了它)。但是我认为它不应该被接受,因为 C++14 [dcl.constexpr/9] 说:

如果在引用声明中使用了 constexpr 说明符,则每个完整的 出现在其初始化程序中的表达式应为常量表达式

并且x 不是常量表达式。

[dcl.constexpr] 的最新 C++17 草案中的语言发生了变化,甚至不再明确提及 constexpr 引用,我无法理解它试图表达的内容他们。

【问题讨论】:

  • 谁说x 不是常量表达式?
  • "x 不是核心常量表达式" {{citation needed}}
  • @T.C. [expr.const]/2 "e 是一个核心常量表达式,除非e 的评估将评估以下之一:[...] 左值到右值转换,除非它应用于 [cases此代码不匹配]"
  • x 被分配了一个字面值,这还不足以让编译器知道它是编译时已知的吗?
  • 如何评估表达式x 需要对其进行左值到右值的转换?

标签: c++ reference c++14 language-lawyer constexpr


【解决方案1】:

假设x 具有静态存储持续时间,则左值表达式x 是一个完全有效的常量表达式。

如果您在需要纯右值的上下文中使用x,这会导致将左值到右值的转换应用于它,那么生成的纯右值表达式 - 称之为TO_RVALUE(x) - 将不是一个常量表达式,原因很明显。但是在引用绑定的情况下,就没有这样的转换了。

【讨论】:

  • 它是否依赖于初始化程序? (例如,int x = rand(); 是否仍然使 x 成为常​​量表达式?)
  • @M.M 否。(是的。)左值常量表达式仅指定实体(基本上,它就像它的地址)。它的初始化是无关紧要的,甚至不需要编译器知道(例如,extern int x; 就足够了)。
猜你喜欢
  • 2019-02-05
  • 2016-07-18
  • 2015-10-22
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多