C++中constexpr引用是否必须仅使用静态对象初始化?
结论
C++标准明确要求constexpr引用的初始化器必须是地址常量表达式,而地址常量表达式只能指向具有静态存储期的对象或函数,因此非静态的自动存储期对象确实不能用来初始化constexpr引用。GCC与Clang的行为符合标准要求,MSVC可编译原始示例属于实现偏差。
规则依据说明
constexpr引用的本质是编译期即可确定绑定目标的引用,它的初始化必须满足常量表达式的要求:
- 对于引用类型的常量表达式,要求其绑定的地址是编译期固定的地址常量
- 函数内非static修饰的变量属于自动存储期,存储在栈空间,每次函数调用时的分配地址都可能发生变化,地址无法在编译期确定,因此无法作为constexpr引用的绑定目标
代码示例说明
不符合标准的原始写法
int main() { constexpr int a = 0; constexpr const int & b = a; }
这里的a虽然是constexpr值类型变量,但属于自动存储期,地址不是编译期常量,因此无法初始化b,GCC、Clang的报错符合标准规范。
符合标准的修正写法
给a添加static修饰后,a变为静态存储期变量,地址在编译期即可确定,满足constexpr引用的初始化要求,所有编译器均可正常编译:
int main() { static constexpr int a = 0; constexpr const int & b = a; }
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

