This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
[Accepted as a DR at the June, 2021 meeting.]
According to 9.4.4 [dcl.init.ref] bullet 5.4.2, when a reference is initialized with a non-class value and the referenced type is not reference-related to the type of the initializer,
Otherwise, the initializer expression is implicitly converted to a prvalue of type “cv1 T1”. The temporary materialization conversion is applied and the reference is bound to the result.
According to 7.2.2 [expr.type] paragraph 2, the cv-qualification is discarded before invoking the temporary materialization conversion:
If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
This results in a reference-to-const being bound to a non-const object, meaning that a const_cast of the reference to a reference-to-nonconst would allow a well-defined modification of the value:
constexpr const int &r = 42; const_cast<int &>(r) = 23; // Well-defined static_assert(r == 42); // Ill-formed, non-constant expression
This was different from the situation before the advent of the temporary materialization conversion in C++17, when the description of the reference binding created the temporary explicitly with the cv-qualified type:
If T1 is a non-class type, a temporary of type “cv1 T1” is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary.
Presumably this difference was unintentional and should be reverted.
Proposed resolution, May, 2021:
Change 9.4.4 [dcl.init.ref] bullet 5.4.2 as follows:
A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
...
Otherwise:
If T1 or T2 is a class type and T1 is not reference-related to T2...
Otherwise, the initializer expression is implicitly converted to a prvalue of type
“cv1T1”. The temporary materialization conversion is applied, considering the type of the prvalue to be “cv1 T1”, and the reference is bound to the result.