Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 理解常量表达式_C++_Language Lawyer - Fatal编程技术网

C++ 理解常量表达式

C++ 理解常量表达式,c++,language-lawyer,C++,Language Lawyer,我试图理解常量表达式的概念(来自): 为什么在我们定义之前,S::c不是一个常量表达式。它被声明为静态常量数据成员,但在此序列中 constexpr int d = 10 * S::c; const int S::c = 5; …编译d值时,S::c的值还未知。但试着交换这些行: const int S::c = 5; constexpr int d = 10 * S::c; 引用C++11标准(草案N3337)第5.19节第2段的相关部分: 条件表达式是核心常量表达式,除非它涉及以下其中一

我试图理解常量表达式的概念(来自):

为什么在我们定义之前,
S::c
不是一个常量表达式。它被声明为静态常量数据成员,但在此序列中

constexpr int d = 10 * S::c;
const int S::c = 5;
…编译
d
值时,
S::c
的值还未知。但试着交换这些行:

const int S::c = 5;
constexpr int d = 10 * S::c;

引用C++11标准(草案N3337)第5.19节第2段的相关部分:

条件表达式是核心常量表达式,除非它涉及以下其中一个作为潜在计算的子表达式(3.2),但不考虑未计算的逻辑AND(5.14)、逻辑OR(5.15)和条件(5.16)运算的子表达式[注:重载运算符调用函数。-结束注]:

  • 左值到右值的转换(4.1),除非应用于

    • 整数或枚举类型的glvalue,它引用具有前面初始化的非易失性常量对象,并用常量表达式初始化
在您对
d
的定义中,前面没有初始化
S::c

编辑:为什么适用:

  • 5.1.1/8
    S::c
    是左值
  • 3.10/1
    :glvalue是左值或xvalue
  • 5/8
    :指定每当使用期望prvalue的运算符时,都会发生从左值到右值的转换
  • 证明乘法需要一个pr值伤了我的头。这在很多地方都有暗示,但我还没有发现任何地方有明确的说法

在C++编译过程中其他初始化之前进行常数初始化。在本例中,

d
的恒定初始化保证在
S::c
的恒定初始化之前发生。常量表达式必须仅由常量值组成。初始化
d
时,
S::c
已知为常量值,因此表达式不被视为常量。

,其中
S::c
永远不是常量表达式<代码>常量通常并不总是意味着常量表达式。@chris谢谢,但现在我比以前更困惑了。。。我试着阅读标准中的5.20,但不明白为什么S::c在这种情况下不是一个核心常量表达式。如果您想让某些内容成为编译时常量,请使用
constexpr
。尽管在某些情况下,
const
意味着
constepr
与C++98兼容。这个答案引用了很长的一段话,没有给出太多解释。这个问题没有提到左值到右值的转换或逻辑运算符。@ross没有,这个答案对我来说太完美了。下面是为什么S::c是整数类型的glvalue。你能解释一下吗?@stella我想我已经尽力了。Standardese让我头疼,即使对一个人说“这很明显”。把这个问题贴上了语言律师的标签。。。
const int S::c = 5;
constexpr int d = 10 * S::c;