Namespaces
Variants

Constant initialization

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

静态 变量的初始值设置为编译期常量。

目录

说明

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

  • 使用常量表达式初始化具有静态存储期的 POD类型 对象。
(C++11 前)
  • 初始化具有 静态 线程 存储期的引用,且满足以下所有条件:
  • 指代具有静态存储期对象的左值
  • 临时对象
  • 临时对象的 子对象
  • 函数
  • 初始化具有静态或线程存储期的对象,且满足以下条件之一:
  • 若对象通过构造函数调用初始化,则初始化全表达式是常量表达式(但允许调用对象及其子对象的 constexpr 构造函数 ,即使这些对象属于非 字面类型 )。
  • 否则,对象进行 值初始化 ,或其初始化器中出现的每个全表达式都是常量表达式。
(C++11 起)
(C++17 前)
(C++17 起)
(C++20 前)
(C++20 起)

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

注释

编译器被允许使用常量初始化来初始化其他静态 和线程局部 (since C++11) 对象,前提是能够保证该值与遵循标准初始化顺序时得到的值完全相同。

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

示例

#include <iostream>
#include <array>
struct S
{
    static const int c;
};
const int d = 10 * S::c; // 不是常量表达式:S::c 没有前置初始化器
                         // 该初始化发生在 const 初始化之后
const int S::c = 5;      // 常量初始化,保证首先执行
int main()
{
    std::cout << "d = " << d << '\n';
    std::array<int, S::c> a1; // 正确:S::c 是常量表达式
//  std::array<int, d> a2;    // 错误:d 不是常量表达式
}

输出:

d = 50

缺陷报告

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

缺陷报告 应用于 发布时的行为 正确行为
CWG 441 C++98 引用无法进行常量初始化 使其可常量初始化
CWG 1489 C++11 值初始化对象是否属于常量初始化
的规定不明确
允许作为常量初始化
CWG 1747 C++11 绑定引用到函数不能作为常量初始化 允许作为常量初始化
CWG 1834 C++11 绑定引用到xvalue不能作为常量初始化 允许作为常量初始化

参见