CWG2894 [expr.type.conv] T{...} Functional casts create prvalues of reference type T (original) (raw)

Reference: [expr.type.conv] paragraph 2, sentence 3

Issue description

In T{...}, if T is a reference type, [expr.type.conv] paragraph 2, sentence 3 applies, stating:

Otherwise, the expression is a prvalue of the specified type whose result object is direct-initialized with the initializer.

This is defective for references; there can be no prvalues of reference type.

Furthermore, it is not sufficiently clear that void(1, 2) and void{1} are not valid. All compilers reject these forms, and should.

Suggested resolution

Update [expr.type.conv] paragraph 2 as follows:

Let T be the specified type. The effect of the expression is as follows:

To [expr.type.conv] paragraph 2, append an example:

void f() { unsigned(-1); // OK, equivalent to (int) -1 unsigned{-1}; // ill-formed, narrowing conversion

void{};           // OK, prvalue of type void
void(1);          // OK, equivalent to (void) 1
void{0};          // ill-formed
void(1, 2);       // ill-formed
int(1, 2);        // ill-formed

struct S { S(int, int); };
S a = S(1, 2);    // OK, S(1, 2) is a prvalue
S b = S(a);       // OK, equivalent to S b = (S) a;

using R = S&;
R r = R(a);       // OK, equivalent to R r = (R) a;
R q = R{a};       // OK, same

}

[Editor's note: The example is intended to be educational and highlight the cases void(1, 2), R{a}, which currently have wording issues or related compiler bugs.]