【问题标题】:Why does the rule defining the term for a constant expression have to be so cluttered?为什么定义常量表达式术语的规则必须如此混乱?
【发布时间】:2015-12-04 15:21:45
【问题描述】:

我不明白为什么由纯右值核心常量表达式引用的临时对象必须没有任何指针或引用,它指向或引用存储持续时间不是静态的对象,以便prvalue核心常量表达式为常量表达式;请参阅 N4296 [expr.const] 5.20\5

我认为实现可以像这样重写该规则:

[expr.const] 5.20\5(修改)

核心常量表达式 e 是一个常量表达式,除非它 初始化一个对象,使其包含一个指针,该指针指向 具有非静态存储持续时间的对象。

如果不是,请有人解释一下原因吗?

【问题讨论】:

  • 您的版本将允许指向具有静态存储持续时间的对象的指针,而该指针又包含指向具有动态存储持续时间的对象的指针。你的版本也不允许空指针。
  • @RaymondChen 嗯...但是空指针值根本不指向任何对象吗?而且我不明白为什么在您的示例中指向具有动态存储持续时间的对象的指针会成为问题。请解释一下。
  • 我想我误解了你的问题。我以为您想将定义改写为与旧定义等效,但更简单。但是,听起来您想更改定义本身。
  • @RaymondChen 是的,它曾经是,现在仍然是一团糟......但我想到了你的空指针值等示例。有趣...
  • 您可能应该指定您引用的标准版本,或引用原始措辞。在我这里的版本中没有 5.20。

标签: c++ language-lawyer


【解决方案1】:

它指向一个存储持续时间不是静态的对象

  1. 您排除了空指针
  2. 您排除了函数指针

从标准 5.20\5:

(5.2) 如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址、超过此类对象末尾的地址 (5.7)、函数的地址或 null指针值

  1. 您省略了将引用作为对象成员的概念。拿他们怎么办?您可以获取运行时对象或静态对象的 const 引用。这是否使整个对象成为core constant expression

(5.1) 每个引用类型的非静态数据成员引用一个实体,该实体是一个常量表达式的允许结果

我敢打赌glvalue core constant expressionprvalue core constant expression 有一个额外的细微差别(据我所知,这个短语不包括xvalue 的一些),但我没能掌握它。我希望有人能解释一下。

一个常量表达式要么是一个泛左值核心常量表达式,它的值是指一个实体,它是一个常量表达式(如下定义)的允许结果,或者是一个纯右值核心常量表达式,它的 值是一个对象

编辑

那有什么问题呢?还有其他规则,你知道的: 5.20\2.7、2.9、2.13、2.19、2.5;等等。 ; )

是的,5.20/2.9 是关于引用的(其他提到的规则不适用于引用类型——据我所知)。让我们读一读。

(2) 条件表达式 e 是核心常量表达式,除非 e 的评估,遵循抽象机的规则 ( 1.9 ),将评估以下表达式之一:
(2.9) 引用变量或数据成员的 id 表达式 引用类型,除非该引用具有前面的初始化和 要么
— (2.9.1) 它用常量表达式初始化或
— (2.9.2) 它是一个对象的非静态数据成员,其生命周期 在 e 的评估中开始;

现在让我们比较一下您的规则和标准。标准为 5.20/2.9 添加了一些细节。

5.20/5
(5.1) 每个引用类型的非静态数据成员引用一个实体,该实体是常量表达式的允许结果
如果实体是具有静态存储持续时间的对象,该对象不是临时对象,或者是其值满足上述约束的临时对象,或者它是一个函数,则该实体是常量表达式的允许结果。

  • 我们再次看到提到了functions(例如使用指针)- 您的规则(基于 5.20/2.9)缺少它。
  • 您的规则中没有提及 object with static storage duration

【讨论】:

  • 是的,我确实做到了。我(几乎)废除了规则:D ...现在可以将常量表达式中的成员引用初始化为引用具有除静态之外的存储持续时间的对象,是的。那么这有什么问题呢?还有其他规则,你知道的:5.20\2.7, 2.9, 2.13, 2.19, 2.5;等等。 ; )
  • 是的,根据我的提议,可能有指向由常量表达式初始化的对象中的函数的指针。这不成问题。函数实际上很好:)它们的地址在编译时是已知的,不是吗?
  • 我在编辑中提到了两个不同之处:对函数的引用(我也记得指向函数的指针,但它们不是重点)和对具有静态存储持续时间的对象的引用。你的规则缺少它们。
  • 引用没有问题,所以没有提及。
  • 问题是什么意思?这两种情况在 5.20/5 之前的早期规则中没有提到,在你的版本中它们只是不存在 const 表达式。这就是区别 - 标准必须包括所有可能的变体,他们不能仅仅因为它对某人来说很明显而忽略任何东西。
猜你喜欢
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 2016-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
相关资源
最近更新 更多