<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>Allow initializing aggregates from a parenthesized list of values</title>

	<style>
	p {text-align:justify}
	li {text-align:justify}
	blockquote.note
	{
		background-color:#E0E0E0;
		padding-left: 15px;
		padding-right: 15px;
		padding-top: 1px;
		padding-bottom: 1px;
	}
	ins {color:#00A000}
	del {color:#A00000}
	</style>
</head>
<body>

<address align=right>
Document number: P0960R0
<br/>
Audience: EWG
<br/>
<br/>
<a href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a><br/>
2018-02-12<br/>
</address>
<hr/>
<h1 align=center>Allow initializing aggregates from a parenthesized list of values</h1>

<h2>Abstract</h2>
<p>
  This paper proposes allowing initializing aggregates from
  a parenthesized list of values; that is, Aggr(val1, val2)
  would mean the same thing as Aggr{val1, val2}. This is a language
  fix for the problem illustrated in
  <a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4462.html">N4462</a>.
</p>

<h2>"This is a completely new way of initializing aggregates
  and adds complexity to the language"</h2>

<p>
  I couldn't disagree more. First of all, this is not a new
  way of initializing aggregates, we can already initialize
  aggregates with parentheses:
</p>

<p>
  <pre>
    <code>
      struct X {int a, b;};
      int main()
      {
          X x{};
          X x2(x); // see, an aggregate initialized with parentheses
      }
    </code>
  </pre>
</p>

<p>
  Second, this makes the language more regular. I can use
  X{1, 2} to initialize an aggregate temporary, but
  X(1, 2) just doesn't work. The only reason for not making
  it work is wishful thinking that everybody would use braced-initialization
  everywhere, but practical deployment experience of C++11 shows
  that that's indeed wishful thinking. The library facilities
  mentioned in N4462 don't use braced-initialization, and can't be
  made to use it because that would be a breaking change. All the lack
  of support for parenthesis-initialization for aggregates leads
  to is programmers adding constructors where they shouldn't need to
  add them, or performing an additional copy/move because that's a way
  to work around the problem.
</p>

<h2>Nested aggregates</h2>

<p>
  Some have asked whether nested aggregates should support
  initialization from a parenthesized list of values that contains
  nested parenthesized lists of values. Akin to
</p>

<p>
  <pre>
    <code>
      struct X {int a, b;};
      struct Y {X x;};
      void f() { Y y{{1,2}};}
    </code>
  </pre>
</p>

<p>
  the question seems to be whether it should be possible
  to write Y y((1,2)) and have it mean the same as
  Y y{{1,2}}. The answer is no. The nested parentheses
  already have a meaning, and there is no use case for adding
  new meaning to nested parentheses.
</p>

<h2>"Can of worms"</h2>

<p>
  Johannes Schaub provided the following example:
</p>

<p>
  <pre>
    <code>
    struct A { int x; };
    A a;
    A b(a);
    </code>
  </pre>
</p>

<p>
  The question was 'Will this try to initialize ".x" by "a", or will it copy a to b?'. The answer is obvious, since it will copy a to b, and it already
  does so today. This proposal doesn't change that in any way, and
  the answer is consistent with "X(a) means X{a} for aggregates".
</p>

<p>
  Johannes had another example:
</p>

<p>
  <pre>
    <code>
      struct A { int x; };
      
      struct B {
         operator A();
      };

      B b;
      A a(b);
    </code>
  </pre>
</p>

<p>
  The question was 'Does it try to convert the "b" to "int" (initializing .x) or to "A"?' The answer is that it will do exactly what A a{b}; would do. There is no can of worms here.
</p>

<h2>"This introcudes new vexing parses"</h2>

<p>
  I don't see how. Every vexing parse I can come up with
  is already vexing today; struct X{int a, b;}; int main() { X x(int(), int());}
  is a valid C++ program where main contains a declaration of a function.
</p>

<h2>Designated initializers</h2>

<p>
  Should X(.a=42, .b=666) be valid? I don't see a pressing need
  to make it so; designated initializers are a C-compatibility
  feature, and that syntax is not a thing in C. For the
  general "X(a) means X{a}", it's plausible to support designated
  initializers.
</p>

<h2>"Please, please make it turn off narrowing prevention!"</h2>

<p>
  There was a strong suggestion on std-proposals to make the parenthesized
  syntax turn off narrowing prevention. EWG feedback on that point is
  welcomed.
</p>

<h2>Arrays</h2>

<p>
  Should arrays be constructible with parentheses? For the sake
  of "X(a) means X{a}", yes. If there is some reason why
  arrays should be an exception, the author of this paper won't
  lose sleep over it.
</p>

<h2>Let's go back to that additional copy/move</h2>

<p>
  An oft-suggested work-around for make_shared&lt;Aggr&gt;(1,2); not working
  is make_shared&lt;Aggr&gt;(Aggr{1,2});. This will incur an extra
  move. That move might not be cheap. That move might not be valid.
  A part of our emplace functions' rationale is to be able to
  do in-place construction to construct even non-copyable
  and non-movable types. With aggregates, this is currently not possible.
</p>


<h2>"I still don't understand why we should do this"</h2>

<p>
  This proposal allows make_shared, make_unique, emplace functions,
  allocator::construct, and a whole host of other things to Just Work
  with aggregate types. We need no library hacks to try and use
  braced initialization if parenthesized initialization isn't valid,
  the library facilities will sprout proper aggregate support as soon
  as this language change is made.
</p>
</body>

</html>
