On Fri, Nov 01, 2019 at 04:37:15PM -0400, Jason Merrill wrote: > 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?
I think I tried and it didn't play well with digest_init and narrowing. If we have { 2.0 } then when recursing on the CONSTRUCTOR element we don't know it came from a paren-init, so a LOOKUP flag was necessary. Marek