On 10/22/19 10:53 AM, Marek Polacek wrote:
This patch implements C++20 P0960R3: Parenthesized initialization of aggregates
(<wg21.link/p0960>; see R0 for more background info).  Essentially, if you have
an aggregate, you can now initialize it by (x, y), similarly to {x, y}.  E.g.

   struct A {
     int x, y;
     // no A(int, int) ctor (see paren-init14.C for = delete; case)
   };
   A a(1, 2);

The difference between ()-init and {}-init is that narrowing conversions are
permitted, designators are not permitted, a temporary object bound to
a reference does not have its lifetime extended, and there is no brace elision.
Further, things like

   int a[](1, 2, 3); // will deduce the array size
   const A& r(1, 2.3, 3); // narrowing is OK
   int (&&rr)[](1, 2, 3);
   int b[3](1, 2); // b[2] will be value-initialized

now work as expected.  Note that

   char f[]("fluff");

has always worked and this patch keeps it that way.  Also note that A a((1, 2))
is not the same as A a{{1,2}}; the inner (1, 2) remains a COMPOUND_EXPR.

The approach I took was to handle (1, 2) similarly to {1, 2} -- conjure up
a CONSTRUCTOR, and introduce LOOKUP_AGGREGATE_PAREN_INIT to distinguish
between the two.  This kind of initialization is only supported in C++20;
I've made no attempt to support it in earlier standards, like we don't
support CTAD pre-C++17, for instance.

Could we use a flag on the CONSTRUCTOR to distinguish between them instead, rather than a LOOKUP flag and a flag in the conversion?

Jason

Reply via email to