我正在尝试初始化constexpr
引用但没有成功。我试过了
#include <iostream>
constexpr int& f(int& x) // can define functions returning constexpr references
{
return x;
}
int main()
{
constexpr int x{20};
constexpr const int& z = x; // error here
}
但我收到了编译错误
错误:constexpr变量&#39; z&#39;必须通过常量表达式初始化
删除const
会导致
错误:对类型&#39; int&#39;的引用绑定类型为&#39; const int&#39;掉落资格赛
即使我感觉constexpr
自动暗示const
变量声明。
所以我的问题是:
constexpr
引用是否有用? (即&#34;更好&#34;比const
参考)答案 0 :(得分:22)
- constexpr引用是否有用? (即&#34;更好&#34;比const引用)
醇>
保证在程序启动之前初始化它们,而在程序开始运行后,可以在动态初始化期间初始化对const的引用。
- 如果是,我该如何有效地定义它们?
醇>
constexpr
引用必须绑定到全局变量,而不是局部变量(或者更正式地说,它必须绑定到具有静态存储持续时间的东西)。
引用在概念上等同于获取变量的地址,并且局部变量的地址不是常量(即使在只能被调用一次的main
中,因此其局部变量仅被初始化一次)。
答案 1 :(得分:9)
所以问题是constexpr引用需要绑定到具有静态存储持续时间的对象,这在draft C++11 standard: N3337部分5.19
[expr.const] 中有所涉及(强调我的):
参考常量表达式是左值 核心常量表达式,用于指定具有静态存储持续时间的对象或函数
draft C++14 standard: N3936更改了措辞:
常量表达式是glvalue核心常量表达式,其值引用具有静态的对象 存储持续时间或函数,或prvalue核心常量表达式,其值是一个对象,其中,for 该对象及其子对象:
- 引用类型的每个非静态数据成员是指具有静态存储持续时间或对象的对象 功能,和
- 如果对象或子对象是指针类型,则它包含具有静态存储的对象的地址 持续时间,超过此类对象(5.7)结尾的地址,函数的地址或空指针 值。
因此,更改x
的声明会起作用:
constexpr static int x{20};
答案 2 :(得分:5)
与T.C.类似,初始化程序需要是具有静态存储持续时间的对象。
N4140 /§5.19/ 4 常量表达式是glvalue核心 常量表达式,其值指的是具有静态的对象 储存期[...]
N4140/§7.1.5/ 9对象声明中使用的
constexpr
说明符 将对象声明为const。这样的对象应具有字面类型 并应初始化。 [...]否则,或constexpr
说明符用于引用声明,每个完整表达式 它在初始化程序中出现的应该是一个常量表达式。
在N3337中,措辞不同。