为什么定义常量表达式的规则必须如此混乱?

Eug*_*sky 14 c++ language-lawyer

我不明白为什么由prvalue核心常量表达式引用的临时对象不能有任何指针或引用,它指向或引用存储持续时间不是静态的对象,以便该prvalue核心常量表达式是一个常量表达式; 见N4296 [expr.const] 5.20\5.

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

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

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

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

Rom*_*sev 1

\n

它指向一个具有除 static 之外的存储持续时间的对象

\n
\n\n
    \n
  1. 您排除了空指针
  2. \n
  3. 您排除了函数指针
  4. \n
\n\n

从标准 5.20\\5 开始:

\n\n
\n

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

\n
\n\n
    \n
  1. 您省略了作为对象成员的引用的概念。该怎么办?您可以获取运行时对象或静态对象的 const 引用。这是否使整个物体存在core constant expression或不存在?
  2. \n
\n\n
\n

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

\n
\n\n

glvalue core constant expression我敢打赌, and还有一个额外的细微差别prvalue core constant expression(据我所知,这个短语排除了一些xvalue),但我无法理解它。我希望有人能解释一下这一点。

\n\n
\n

常量表达式可以是泛左值核心常量表达式,其值引用作为常量表达式允许的结果的实体(如下定义),也可以是纯右值核心常量表达式,其值是对象

\n
\n\n

编辑

\n\n
\n

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

\n
\n\n

是的,5.20/2.9是关于引用的(其他提到的规则不适用于引用类型 - 据我了解)。我们来读一下吧。

\n\n
\n

(2) 条件表达式 e 是核心常量表达式,除非 e 的计算遵循抽象机的规则 (\n 1.9 ),将计算以下表达式之一:
\n (2.9) 一个 id-引用引用类型的变量或数据成员的表达式,除非该引用具有前面的初始化并且\n
\n \xe2\x80\x94 (2.9.1) 使用常量表达式或
\n \xe2进行初始化\x80\x94 (2.9.2) 它是一个对象的非静态数据成员,其生命周期开始于 e 的求值内;

\n
\n\n

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

\n\n
\n

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

\n
\n\n
    \n
  • 我们再次看到提到functions(就像指针一样)-您的规则(基于5.20/2.9)缺少它。
  • \n
  • object with static storage duration您的规则中没有提及提及
  • \n
\n