了解常量表达式
Understanding constant expression
我正在尝试理解常量表达式概念(来自 c++reference):
struct S {
static const int c;
};
const int d = 10 * S::c; // not a constant expression: S::c has no preceding
// initializer, this initialization happens after const
const int S::c = 5; // constant initialization, guaranteed to happen first
为什么 S::c
在我们定义它之前不是常量表达式。尽管它被声明为静态 const 数据成员...
在这个序列中……
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 段:
A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression (3.2), but subexpressions of logical AND (5.14), logical OR (5.15), and conditional (5.16) operations that are not evaluated are not considered [ Note: An overloaded operator invokes a function. — end note ]:
an lvalue-to-rvalue conversion (4.1) unless it is applied to
- a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression
在你定义的 d
中没有预先初始化 S::c
。
编辑:为什么适用:
5.1.1/8
: S::c
是一个左值。
3.10/1
: glvalue 是左值或 xvalue。
5/8
:指定只要使用需要纯右值的运算符,就会发生左值到右值的转换。
- 证明乘法需要一个纯右值让我很头疼。它在很多地方都有暗示,但我没有找到任何地方明确。
常量初始化在C++编译过程中先于其他初始化进行。在示例中,d
的常量初始化保证在 S::c
的常量初始化之前发生。常量表达式必须完全由常量值组成。初始化 d
时,已知 S::c
是常量值,因此表达式不被视为常量。
我正在尝试理解常量表达式概念(来自 c++reference):
struct S {
static const int c;
};
const int d = 10 * S::c; // not a constant expression: S::c has no preceding
// initializer, this initialization happens after const
const int S::c = 5; // constant initialization, guaranteed to happen first
为什么 S::c
在我们定义它之前不是常量表达式。尽管它被声明为静态 const 数据成员...
在这个序列中……
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 段:
A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression (3.2), but subexpressions of logical AND (5.14), logical OR (5.15), and conditional (5.16) operations that are not evaluated are not considered [ Note: An overloaded operator invokes a function. — end note ]:
an lvalue-to-rvalue conversion (4.1) unless it is applied to
- a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression
在你定义的 d
中没有预先初始化 S::c
。
编辑:为什么适用:
5.1.1/8
:S::c
是一个左值。3.10/1
: glvalue 是左值或 xvalue。5/8
:指定只要使用需要纯右值的运算符,就会发生左值到右值的转换。- 证明乘法需要一个纯右值让我很头疼。它在很多地方都有暗示,但我没有找到任何地方明确。
常量初始化在C++编译过程中先于其他初始化进行。在示例中,d
的常量初始化保证在 S::c
的常量初始化之前发生。常量表达式必须完全由常量值组成。初始化 d
时,已知 S::c
是常量值,因此表达式不被视为常量。