Consider an example like:
constexpr int f() { return 5; }
constexpr int && q = f();
constexpr int const & r = 2;
int main() {
q = 11;
const_cast< int & >( r ) = 3;
constexpr int && z = 7;
}
A constexpr reference must be initialized by a constant expression
(7.1.5 [dcl.constexpr] paragraph 9), yet it may refer to a modifiable
temporary object. Such a temporary is guaranteed static
initialization, but it's not ROMable.
A non-const constexpr reference initialized with an lvalue expression
is useful, because it indicates that the underlying storage of the
reference may be statically initialized, or that no underlying storage
is required at all.
When the initializer is a temporary, finding its address is trivial.
There is no reason to declare any intent the computation of its
address. On the other hand, an initial value is provided, and that is
also required to be a constant expression, although it's never treated
as a constant.
The situation is worse for local constexpr references. The initializer
generates a temporary when the declaration is executed. The temporary
is a locally scoped, unique object. This renders constexpr
meaningless, because although the address computation is trivial, it
still must be done dynamically.
C++11 constexpr references required initialization by reference
constant expressions, which had to “designate an object with static
storage duration or a function” (C++11 5.20 [expr.const] paragraph 3).
A temporary with automatic storage duration granted by the reference
fails this requirement.
C++14 removes reference constant expressions and the static storage
requirement, rendering the program well-defined with an apparently
defeated constexpr specifier. (GCC and Clang currently provide the
C++11 diagnosis.)
Suggested resolution: a temporary bound to a constexpr reference
should itself be constexpr, implying const-qualified type. Forbid
binding a constexpr reference to a temporary unless both have static
storage duration. (In local scope, the static specifier fixes the
issue nicely.)
N4140
没有5.20。 - stackcpp