命名空间
变体
操作

常量初始化

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
range-for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 在 C++17* 前已弃用)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
聚合初始化
列表初始化 (C++11)  
常量初始化
引用初始化

 
 

static 变量的初始值设置为编译时常量。

目录

[编辑] 解释

常量初始化 在以下情况下执行

  • 使用常量表达式初始化具有静态存储期的 POD 类型 的对象。
(C++11 前)
  • 初始化具有 静态线程 存储期的引用,其中满足以下所有条件
  • 一个左值,指代具有静态存储期的对象
  • 一个临时对象
  • 临时对象的 子对象
  • 一个函数
  • 初始化具有静态或线程存储期的对象,并且满足以下条件之一
  • 如果对象是通过构造函数调用初始化的,其中初始化完整表达式是一个常量表达式,但它也可能为对象及其子对象调用 constexpr 构造函数(即使这些对象是非 字面量 类类型)。
  • 否则,对象要么是 值初始化 的,要么出现在其初始化器中的每个完整表达式都是一个常量表达式。
(自 C++11 起)
(C++17 前)
(自 C++17 起)
(C++20 前)
(自 C++20 起)

常量初始化的效果与相应初始化的效果相同,但保证它在任何其他静态 或线程局部(自 C++11 起)对象开始初始化之前完成。

[编辑] 注解

如果编译器可以保证该值与遵循标准初始化顺序时的值相同,则允许编译器使用常量初始化来初始化其他静态 和线程局部(自 C++11 起)对象。

常量初始化通常在程序加载到内存时发生,作为初始化程序运行时环境的一部分。

[编辑] 示例

#include <iostream>
#include <array>
 
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
 
int main()
{
    std::cout << "d = " << d << '\n';
    std::array<int, S::c> a1; // OK: S::c is a constant expression
//  std::array<int, d> a2;    // error: d is not a constant expression
}

输出

d = 50

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
CWG 441 C++98 引用不能被常量初始化 使其可常量初始化
CWG 1489 C++11 不清楚值初始化是否
对象可以是常量初始化
它可以
CWG 1747 C++11 将引用绑定到函数不能是常量初始化 它可以
CWG 1834 C++11 将引用绑定到 xvalue 不能是常量初始化 它可以

[编辑] 参见