Closed
Description
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:
LetT
be the specified type. The effect of the expression is as follows:
- If the initializer is a parenthesized single expression, the type conversion expression is equivalent to the corresponding cast expression.
- Otherwise, if
the typeT
is cvvoid
and the initializer isthe initializer shall be()
or{}
(after pack expansion, if any), and the expression is a prvalue of typevoid
that performs no initialization.- Otherwise, the expression
is a prvalue of the specified type whose result object is direct-initialized with the initializerhas the same effect as direct-initializing an invented variableT t
with the given initializer and then usingt
as the result of the expression. The result is an lvalue if the specified typeT
is an lvalue reference type or reference to function type, an xvalue ifT
is an rvalue reference to object type, and a prvalue otherwise. If the initializer is a parenthesized optional expression-list, the specified type shall not be an array type.
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.]
Metadata
Metadata
Assignees
Labels
No labels