Consider an example of the type:
constexpr int f() { return 5; } // function must be constexpr constexpr int && q = f(); // but result is not constant constexpr int const & r = 2; // temporary is still not constant int main() { q = 11; // OK const_cast< int & >( r ) = 3; // OK (temporary object is not ROMable) constexpr int && z = 7; // Error? Temporary does not have static storage duration? }
A reference to constexpr must be initialized with a constant expression (7.1.5 [dcl.constexpr], clause 9), however it can refer to a mutable temporary object. Such a temporary guaranteed static initialization, but it is not writable.
The non-constant constexpr reference initialized with the lvalue expression is useful because it indicates that the underlying storage link may be statically initialized or that no base storage is required at all.
When the initializer is temporary, the search for its address is trivial. There is no reason to declare any intentions to the address. On the other hand, an initial value is provided, and it is also required to be a constant expression, although it has never been treated as a constant.
The situation is worse for local constexpr links. The initializer generates a temporary expression when the declaration is executed. Temporary is a locally restricted, unique object. This displays constexpr pointless, because although address computation is trivial, it still needs to be done dynamically.
C ++ 11 constexpr constants require initialization by reference of constant expressions that were supposed to “assign an object with a static storage duration or function” (C ++ 11 5.20 [expr.const], clause 3). Temporary with automatic storage duration provided by the link does not meet this requirement.
C ++ 14 removes reference constant expressions and static storage requirement, which ensures the correct operation of the program with the explicitly defeated constexpr constructor. (GCC and Clang currently provide C ++ 11.)
Proposed resolution: a temporary reference to a constexpr reference must itself be constexpr, implying a const-qualified type. prohibit the linking of constexpr links to temporary ones, if both of them do not have a static storage period. (In the local area, the static specifier captures well.)