<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>Aggregate initialization in the presence of deleted constructors</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: P1090
<br/>
Audience: EWG
<br/>
<br/>
<a href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a><br/>
2018-05-07<br/>
</address>
<hr/>
<h1 align=center>Aggregate initialization in the presence of deleted constructors</h1>

<h2>Abstract</h2>
<p>
  This paper describes an alternative solution to Timur Doumler's paper
  for making class types with user-declared constructors non-aggregates.
  The gist of the difference is that this alternative treats implicitly
  deleted and explicitly deleted constructors the same way, and provides
  a different design principle - in the approach described, deleted
  constructors subtract from an overload set but do not necessarily
  establish such a set, i.e. they turn off specific forms of aggregate
  initialization but not all of them.
</a>.
</p>

<h2>Jacksonville 2018 discussion feedback</h2>

<p>
  In Jacksonville, when discussing P0960, the following feedback was
  given by EWG:
  <ul>
    <li>Incorporate ban brace-initializing an object if it would be plausible that it would use a deleted constructor? 11 | 14 | 5 | 0 | 3</li>
  </ul>
</p>
<p>
  This paper and Timur's paper separate out aggregate initialization
  in the presence of deleted constructors.
</p>

<h2>Why another approach?</h2>

<p>
  Timur's approach makes class types with user-declared constructors
  non-aggregates. This means that
  <pre><code>
    struct X1 {int& x;};
  </code></pre>
  and
  <pre><code>
    struct X2 {int& x; X2() = delete;};
  </code></pre>
  behave differently. Both of those types have a deleted default
  constructor, but even in the new approach, X1 remains an aggregate.
  X1 can be brace-initialized with a value, X2 cannot.
</p>
<p>
  Another point of contention is the following:
  <pre><code>
      struct X3 {int a, b; X3() = delete;};
      X3 x{1,2}; // is this reasonable?
    </code></pre>
</p>

<p>
  I'm not sure we can do much more than guesswork on what
  does or does not make sense to programmers, but to me,
  it makes sense that deleting a default constructor
  deletes initializations that don't provide values, whereas
  initializations that do provide values are unaffected
  by it.
</p>

<p>
  To be fair, there are other examples where it's anything
  but obvious what is or is not obvious. :) Such as
  <pre><code>
      struct X4 {int a, b, c; X4(int, int) = delete;};
      X4 x{42}; // ok
      X4 x2{}; // ok
      X4 x3{1, 2}; // ill-formed
      X4 x4{1,2,3}; // ok
  </code></pre>
</p>
<p>
  Timur's proposal makes all those initializations uniformly
  ill-formed.
</p>
<p>
  The non-obvious part is that user-declaring a non-deleted
  constructor would make that constructor the only valid
  initialization signature (except for copy/move, from a single object),
  but user-declaring a deleted constructor doesn't do that.
  I admit that the suggested mental model of "deleted constructor
  subtracts from the overload set but doesn't necessarily establish it"
  is not the strongest model I've seen. It does seem workable, though. It
  makes sense to me that the user wanted to remove a two-parameter
  signature from the set of valid initialization signatures. The rest
  is convenience; if we believe that it's likely that such selective
  removal is expected, this is a more convenient approach than
  saying "if you ever declare a constructor, you will need to
  declare the full set". We already require so for non-deleted constructors,
  though.
</p>

<h3>Pseudo-wording</h3>

<p>
  It's perhaps easier to understand my approach in terms
  of wording. So, in [dcl.init.list]/3.4, we do something like
  <blockquote>
    Otherwise, if T is an aggregate, <ins> constructors are considered. If
      a viable constructor is found, but initializing T with a constructor
      would be ill-formed, the program
    is ill-formed. Otherwise, </ins>aggregate initialization is performed.
  </blockquote>
</p>
</body>

</html>
