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

Reply via email to