如何初始化一个 constexpr 引用

how to initialize a constexpr reference

我正在尝试初始化一个 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
}

但我遇到编译时错误

error: constexpr variable 'z' must be initialized by a constant expression

删除 const 结果是

error: binding of reference to type 'int' to a value of type 'const int' drops qualifiers

尽管我觉得 constexpr 自动暗示变量声明为 const

所以我的问题是:

  1. constexpr 参考有用吗? (即 "better" 比 const 引用)
  2. 如果是,我怎样才能有效地定义它们?

PS:我看到了几个与我相关的问题,例如 Which values can be assigned to a `constexpr` reference?,但我认为它们没有解决我的问题。

  1. Are constexpr references ever useful? (i.e., "better" than const references)

它们保证在程序启动之前被初始化,而对 const 的引用可以在程序启动之后动态初始化期间初始化 运行。

  1. If yes, how can I effectively define them?

constexpr 引用必须绑定到全局变量,而不是局部变量(或者更正式地说,它必须绑定到具有静态存储持续时间的对象)。

引用在概念上等同于获取变量的地址,局部变量的地址不是常量(即使在只能调用一次的main中,它的局部变量也只是初始化一次)。

所以问题是 constexpr 引用需要绑定到具有静态存储持续时间的对象,这在 draft C++11 standard: N3337 部分 5.19 [expr.const]强调我的):

A reference constant expression is an lvalue core constant expression that designates an object with static storage duration or a function

draft C++14 standard: N3936修改写法:

A constant expression is either a glvalue core constant expression whose value refers to an object with static storage duration or to a function, or a prvalue core constant expression whose value is an object where, for that object and its subobjects:

  • each non-static data member of reference type refers to an object with static storage duration or to a function, and
  • if the object or subobject is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object (5.7), the address of a function, or a null pointer value.

所以像这样更改 x 的声明会起作用:

constexpr static int x{20};

所说,初始化器需要是一个具有静态存储持续时间的对象。

N4140/§5.19/4 A constant expression is either a glvalue core constant expression whose value refers to an object with static storage duration [...]

N4140/§7.1.5/9 A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. [...] Otherwise, or if a constexpr specifier is used in a reference declaration, every full-expression that appears in its initializer shall be a constant expression.

在N3337中,写法不同