<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<title>Fixing is_constructible and is_explicitly_convertible</title>

<style type="text/css">
  p {text-align:justify}
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  blockquote.note
  {
   background-color:#E0E0E0;
   padding-left: 15px;
   padding-right: 15px;
   padding-top: 1px;
   padding-bottom: 1px;
  }
</style>
</head><body>
<address style="text-align: left;">
Document number: N3047=10-0037<br>
Project: Programming Language C++, Library Working Group<br>
Author: <a href="mailto:daniel.kruegler@googlemail.com">Daniel Krgler</a><br>
Date: 2010-03-01
</address>
<hr>
<h1 style="text-align: center;">Fixing <tt>is_constructible</tt> and <tt>is_explicitly_convertible</tt></h1>

<h2><a name="Introduction"></a>Introduction</h2>

<p>
The <tt>is_constructible</tt> component is a fundamental type property trait that describes whether
some type <tt>T</tt> can be constructed from a set of other types <tt>Args</tt>
<p>
<blockquote><pre>
  template &lt;class T, class... Args&gt; 
  struct is_constructible;
</pre></blockquote>
<p>
This trait is also used to specify semantics of other standard components within the allocator framework and will probably help
to specify <tt>std::bind</tt> as part of library issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#817">817</a>.
During it's initial specification by <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2984.htm">N2984</a> an 
expression-based approach was used:
<p>
<blockquote class="note"><p>
  Given the following function prototype:
<pre>
  template &lt;class T&gt;
  typename add_rvalue_reference&lt;T&gt;::type create();
</pre><p>
  the predicate condition for a template specialization <tt>is_constructible&lt;T, Args...&gt;</tt> shall be satisfied if
  and only if the following expression <em>CE</em> would be well-formed:<br>
  <ul>
  <li>if <tt>sizeof...(Args) == 1</tt>, the expression:<p>
    <tt>static_cast&lt;T&gt;(create&lt;Args&gt;()...)</tt>
  </li>
  <li>otherwise, the expression:<p>
    <tt>T(create&lt;Args&gt;()...)</tt>
  </li>
  </ul>
</blockquote>
<p>
The special handling of the 1:1 conversion case using <tt>static_cast</tt> is necessary, because otherwise the expression would
be interpreted equivalent to a <em>C cast</em> (5.4 [expr.cast]) and would thus accept unwanted <tt>const</tt>-breaking casts or 
reinterpreting casts as well.
<p>
The special unary transformation case also provides a natural replacement for the concept <tt>ExplicitlyConvertible&lt;T, U&gt;</tt> as
a C++ type trait and was thus recommended to be added as well. A simple but sufficient definition <strong>given the above definition of 
<tt>is_constructible</tt></strong> would look like this:
<p>
<blockquote><pre>
  template &lt;class T, class U&gt; 
  using is_explicitly_convertible = is_constructible&lt;U, T&gt;;
</pre></blockquote>
<p>
This definition of the <tt>is_explicitly_convertible</tt> trait has some remarkable properties: In fact, it is a perfect
<em>refinement</em> of the <tt>is_convertible</tt> trait, because it evaluates to <tt>true</tt> for all expressions,
for which <tt>is_convertible</tt> evaluates to <tt>true</tt>, including the special corner cases, namely that 
<tt><em>cv</em> void</tt> can be converted to <tt><em>cv</em> void</tt>. It extends this corner-case by evaluating to <tt>true</tt>
for <em>all</em> conversions of any expression of type <tt>T</tt> to <tt><em>cv</em> void</tt> (5.2.9 [expr.static.cast]).
<p>
Alas, there is a downside of the current definition of the <tt>is_constructible</tt> trait, as described by library issue
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1260">1260</a>: The need to fall back to a
<tt>static_cast</tt> in the 1:1 conversion will also allow for even more explicitness during a construction, e.g.
the conversion of <tt>void*</tt> to <tt>int*</tt> or a down-cast within a class hierarchy. And these conversions
would not be well-formed during a normal construction as part of a member initializer or of any variable definition like this:
<p>
<blockquote><pre>
	T t(u);
</pre></blockquote>
<p>
where <tt>u</tt> is a value of type <tt>U</tt>. So, in fact, the <tt>is_constructible</tt> trait would return <em>false positives</em>
if testing for a well-formed direct initialization and this must be fixed.
<p>

<h2><a name="Discussion"></a>Discussion</h2>

<p>
The currently proposed resolution of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1260">1260</a> suggests
the following wording change by replacing the expression-based approach by a more appropriate variable-definition:
<p>
<blockquote class="note"><p>
  Given the following function prototype:
<pre>
  template &lt;class T&gt;
  typename add_rvalue_reference&lt;T&gt;::type create();
</pre><p>
  the predicate condition for a template specialization <tt>is_constructible&lt;T, Args...&gt;</tt> shall be satisfied if
  and only if the following <del>expression <em>CE</em></del><ins>variable definition</ins> would be well-formed:<br>
  <ul>
  <li>if <tt>sizeof...(Args) == <ins>0</ins><del>1</del></tt><del>, the expression</del>:<p>
    <del><tt>static_cast&lt;T&gt;(create&lt;Args&gt;()...)</tt></del>
    <ins><tt>T t;</tt></ins>
  </li>
  <li>otherwise<del>, the expression</del>:<p>
    <tt>T<ins> t</ins>(create&lt;Args&gt;()...)<ins>;</ins></tt>
  </li>
  </ul>
</blockquote>
<p>
This approach would indeed solve the overshooting explicitness, but it has the following disadvantages:
<p>
<ol>
<li>It has the effect that any <tt>DefaultConstructible</tt> type <tt>T</tt> that requires value-initialization, like <tt>const int</tt>, will
	not satisfy the <tt>is_constructible</tt> predicate condition. Nevertheless these types are usually considered as &quot;constructible&quot;.
	It is worth mentioning that the currently proposed wording to define the yet missing <tt>DefaultConstructible</tt> requirements as of library issue
	<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#724">724</a>
	was written to ensure that every <tt>const T</tt> for which <tt>T</tt> satisfies the <tt>DefaultConstructible</tt> requirements 
	does also satisfy the <tt>DefaultConstructible</tt> requirements. This is realized by using different symbols for the
	constructed entities.
</li>
<li>It has the unfortunate effect, that <tt>is_explicitly_convertible</tt> is no longer a refinement of <tt>is_convertible</tt>, because
	some corner conversion cases will no longer be well-formed, i.e. all conversions to <tt><em>cv</em> void</tt>.
</li>
</ol>
<p>
Fortunately, it is rather easy to fix the first problem by taking advantage of the fact that a pack expansion with an empty parameter pack 
is still evaluated as a variable definition (and not as a function declaration). Core language experts confirmed that the syntactic 
disambiguation must be done with the original concrete tokens. This would simplify and unify the variable definition to:
<p>
<blockquote><pre>
  <tt>T t(create&lt;Args&gt;()...);</tt>
</pre></blockquote>
<p>
with the wanted outcome that <tt>const</tt> types are also supported as being default-constructible. Another important aspect we would
like to ensure is that this syntax also works with value-initialization of arrays. While value-initialization of arrays is
defined since C++03, it was not really clear that this would be possible with the <tt>()</tt> syntax. Fortunately, the bulleted
list of [dcl.init]/16 has been reworded for C++0x to actively support this construction syntax for arrays as well, see
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3035.pdf">N3035</a>.
<p>
The remaining question is, in which way the also affected <tt>is_explicitly_convertible</tt> trait should be repaired.
The basic choices are:
<p>
<ol>
<li>Fix <tt>is_explicitly_convertible</tt> by returning to the current <tt>static_cast</tt> expression, no longer
	making <tt>is_explicitly_convertible</tt> dependent on <tt>is_constructible</tt>.
</li>
<li>Remove <tt>is_explicitly_convertible</tt> from the standard.
</li>
</ol>
<p>
The first choice was considered, but it turned out that there exist quite different understandings of what &quot;explicitly convertible&quot;
should actually mean. While some believe that <tt>static_cast</tt> correctly expresses this, others believed that the fixed
<tt>is_constructible</tt> would provide a better meaning for <tt>is_explicitly_convertible</tt> as well. Therefore this paper
recommends to remove the <tt>is_explicitly_convertible</tt> from the working draft. This should do no harm now, because
nothing depends on that special definition yet. And if it turns out, that the trait would still be useful, it could be
added in another revision of the standard.
<p>

<h3><a name="InitLists">What about <em>list-initialization</em>?</a></h3>
<p>	
Using the braced-enclosed inititializer syntax either as an expression as in
<p>
<blockquote><pre>
  <tt>T{create&lt;Args&gt;()...}</tt>
</pre></blockquote>
<p>
or as a variable definition as in:
<p>
<blockquote><pre>
  <tt>T t{create&lt;Args&gt;()...};</tt>
</pre></blockquote>
<p>
was indeed considered. But it was decided to better stay away from list-initialization in the definition
of the <tt>is_constructible</tt> trait, because parentheses-based constructions are the only-known
general construction syntax in C++03 and because brace-based constructions do follow several
different rules (e.g. they prevent <em>narrowing conversions</em> and may prefer a better matching
<em>initializer-list constructor</em>), which are not really compatible
with the <tt>()</tt> syntax. Without wanting to break user-code, most library parts need to refer to
the parentheses, though, at least in the generic code parts. Nevertheless, list-initializations are
expected to become very popular and it is recommended to consider to provide a corresponding
construction trait, e.g. <tt>is_list_constructible</tt>, in the next revision of the standard.
<p>		
<h2><a name="Proposed_resolution"></a>Proposed resolution</h2>
<p>
<strong>If applied, this proposal will resolve library issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1260">1260</a></strong>.
<p>
<ol>
<li>Change [meta.type.synop], header <tt>&lt;type_traits&gt;</tt> synopsis as indicated:
<p>
<blockquote><pre>
namespace std {
  ...
  // 20.7.5, type relations:
  template &lt;class T, class U&gt; struct is_same;
  template &lt;class Base, class Derived&gt; struct is_base_of;
  template &lt;class From, class To&gt; struct is_convertible;
  <del>template &lt;class From, class To&gt; struct is_explicitly_convertible;</del>
  ...
}
</pre></blockquote>
</li>
<li>Change [meta.unary.prop]/6 as indicated:
<p>
<blockquote><p>
  Given the following function prototype:
<pre>
  template &lt;class T&gt;
  typename add_rvalue_reference&lt;T&gt;::type create();
</pre><p>
  the predicate condition for a template specialization <tt>is_constructible&lt;T, Args...&gt;</tt> shall be satisfied if
  and only if the following <del>expression <em>CE</em></del><ins>variable definition</ins> would be well-formed:<br>
  <blockquote><p>
    <ins><tt>T t(create&lt;Args&gt;()...);</tt></ins>
  </blockquote>
  <ins>[<em>Note</em>: These tokens are never interpreted as a function declaration. &mdash; <em>end note</em>]</ins>
  <ul>
  <li><del>if <tt>sizeof...(Args) == 1</tt>, the expression:<p></del>
  <del><tt>static_cast&lt;T&gt;(create&lt;Args&gt;()...)</tt></del>
  </li>
  <li><del>otherwise, the expression:<p></del>
  <del><tt>T(create&lt;Args&gt;()...)</tt></del>
  </li>
</ul>
</blockquote>
<p>
</li>
<li>Change in [meta.unary.prop] as indicated:<p>
<blockquote>
<table border="1">
<caption>Table 43 &mdash; Type property predicates</caption>

<tbody>
<tr>
<th>Template</th>
<th>Condition</th>
<th>Preconditions</th>
</tr>

<tr>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
</tr>
<tr>
<td><tt>template &lt;class T, class... Args&gt;</tt><br>
<tt>struct is_nothrow_constructible;</tt></td>
<td><tt>is_constructible&lt;T, Args...&gt;::value</tt> is <tt>true</tt><br>
and the <del>expression <em>CE</em></del><ins>variable definition</ins>, as defined <em>below</em>, is known<br>
not to throw any exceptions.</td>
<td><tt>...</tt></td>
</tr>
<tr>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
</tr>

</tbody></table>
</blockquote>

</li>
<li>Change in [meta.rel] as indicated:<p>
<blockquote>
<table border="1">
<caption>Table 45 &mdash; Type relationship predicates</caption>

<tbody>
<tr>
<th>Template</th>
<th>Condition</th>
<th>Comments</th>
</tr>

<tr>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
</tr>
<tr>
<td><del><tt>template &lt;class From, class To&gt;</tt><br>
<tt>struct is_explicitly_convertible;</tt></del></td>
<td><del><tt>is_constructible&lt;To, From&gt;::value</tt></del></td>
<td><del><tt>is_explicitly_convertible</tt> is<br>
a synonym for a two-argument version of<br>
<tt>is_constructible</tt>.An implementation may define<br> 
it as a template alias.</del></td>
</tr>
<tr>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
</tr>

</tbody></table>
</blockquote>
</li>
</ol>
<p>

<h2><a name="Akn"></a>Acknowledgements</h2>
<p>
I would like to thank Peter Dimov for pointing out the defect in the <tt>is_constructible</tt> definition, and 
Howard Hinnant for his very helpful discussions and comments during reviews of this paper. The generous help of 
Stephen Adamczyk, Mike Miller, and John Spicer in interpreting core wording is much appreciated. Further thanks to
Alberto Ganesh Barbati, Niels Dekker, and Peter Dimov for discussing <tt>MoveConstructible</tt> requirements
in the context of this proposal.
</p>
</body></html>