﻿<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
    <meta charset="UTF-8"/>
    <title>convert() utility function</title>
<style type="text/css">
body {color: #000000; background-color: #FFFFFF;}

del {text-decoration: line-through; color: #8B0040;}
ins {text-decoration: underline; color: #005100;}

pre code {display: inline-block; white-space: inherit}
code {white-space: nowrap}
code wbr {white-space: normal}

/*
.wording { max-width: 90ex; }
.wording .sectnum { margin-right: 1em; }
.wording .sectname { display: block; float: right;  }

section.numbered { counter-reset: par-num; }
.wording p:before, .wording dt:before {
    content: counter(par-num) " "; counter-increment: par-num;
    font-size: 80%; position: absolute; left: 2em}
*/
.wording td { border-top: thin solid black; border-bottom: thin solid black; }

section.function { clear: both; }
.attributes, .attribute {margin-left: 2em}

.docinfo {float: right}
.docinfo p {margin: 0; text-align:right; font-style: italic}

section {padding-left: 1em}
section header {margin-left: -1em}

h2, h3, h4, h5, h6 { margin-bottom: .75em }
h5, h6 { font-size: 1em; }
p {margin-top: .5em; margin-bottom: .5em}
p:first-child, ul, ol {margin-top: 0}
.todo dt:not(:first-child) {margin-top: .5em}
p, li, dd, table {max-width: 80ex}

table { border: double; margin: 1em; border-collapse: collapse; }
caption { white-space: pre; }
td { text-align: left; }


.example {display: inline-block; clear: both; margin-left: 1ex;
          border: thin solid #0e0; background-color: #f8f8f8; padding: 1ex}

.ednote {display: inline-block; clear: both; margin-left: 1ex;
         border: thin solid #0e0; background-color: #f8f8f8; padding: 1ex}

div.ednote > *:first-child::before {content: "Note: "; display: inline; font-weight: bold}
div.ednote {display: inline-block; margin-left: 1ex; border: thin solid #fb6;
            padding: 1ex; background-color: #fff4dd}

:target {background-color: #fed}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">//<![CDATA[
$(function() {
    var next_id = 0
    function find_id(node) {
        // Look down the first children of 'node' until we find one
        // with an id. If we don't find one, give 'node' an id and
        // return that.
        var cur = node[0];
        while (cur) {
            if (cur.id) return cur.id;
            if (cur.tagName == 'A' && cur.name)
                return cur.name;
            cur = cur.firstChild;
        };
        // No id.
        node.attr('id', 'gensection-' + next_id++);
        return node.attr('id');
    };

    // Put a table of contents in the #toc nav.

    // This is a list of <ol> elements, where toc[N] is the list for
    // the current sequence of <h(N+2)> tags. When a header of an
    // existing level is encountered, all higher levels are popped,
    // and an <li> is appended to the level
    var toc = [$("<ol/>")];
    $(':header').not('h1').each(function() {
        var header = $(this);
        // For each <hN> tag, add a link to the toc at the appropriate
        // level.  When toc is one element too short, start a new list
        var levels = {H2: 0, H3: 1, H4: 2, H5: 3, H6: 4};
        var level = levels[this.tagName];
        if (typeof level == 'undefined') {
            throw 'Unexpected tag: ' + this.tagName;
        }
        // Truncate to the new level.
        toc.splice(level + 1, toc.length);
        if (toc.length < level) {
            // Omit TOC entries for skipped header levels.
            return;
        }
        if (toc.length == level) {
            // Add a <ol> to the previous level's last <li> and push
            // it into the array.
            var ol = $('<ol/>')
            toc[toc.length - 1].children().last().append(ol);
            toc.push(ol);
        }
        var header_text = header.text();
        toc[toc.length - 1].append(
            $('<li/>').append($('<a href="#' + find_id(header) + '"/>')
                              .text(header_text)));
    });
    $('#toc').append(toc[0]);
})
//]]></script>
</head>
<body>
  <header>
    <div class="docinfo">
      <p>ISO/IEC JTC1 SC22 WG21 N3521</p>
      <p>Date: <time pubdate="">2013-01-12</time></p>
      <address>
        <p>Jeffrey Yasskin &lt;<a href="mailto:jyasskin@google.com">jyasskin@google.com</a>&gt;</p>
      </address>
    </div>
    <h1><code>convert()</code> utility function</h1>
  </header>
  <p><small><a href="#maincontent">Skip table of contents</a></small></p>
  <nav id="toc"></nav>
  <a id="maincontent"></a>
  <section>
    <header><h2 id="overview">Overview</h2></header>
    <p>A few recent threads have expected either <code>return ptr;</code>
    <small>(Bjarne Stroustrup in c++std-ext-14038)</small> or
    <code>foo({ptr})</code> <small>(<a
    href="https://groups.google.com/a/isocpp.org/d/topic/std-proposals/YBnWHvd_dIY/discussion">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/YBnWHvd_dIY/discussion</a>)</small>
    to invoke the explicit <code>unique_ptr(T*)</code> constructor.  Both
    threads eventually proposed a list of language changes to make the necessary
    conversion more concise:</p>

    <ul>
      <li><code>auto{ptr}</code></li>
      <li>Declare <code>explicit <em>listinit</em> unique_ptr(pointer
      p)</code> to allow <code>{ptr}</code> to work.</li>
      <li><code>return explicit({ new foo });</code></li>
      <li><code>auto return ptr;</code></li>
      <li><code>explicit return x</code> or <code>return explicit x</code></li>
      <li>If the object in question is local, the explicit constructor can be
      bypasssed in the <code>return</code> statement. (By analogy to the rule for move constructors.)</li>
    </ul>

    <p>In c++std-ext-14049 and independently in <a
    href="https://groups.google.com/a/isocpp.org/d/msg/std-proposals/YBnWHvd_dIY/2iBLM-fAqngJ">https://groups.google.com/a/isocpp.org/d/msg/std-proposals/YBnWHvd_dIY/2iBLM-fAqngJ</a>,
    I and Vicente J. Botet Escriba proposed a library solution to handle this
    problem with a single extra token:</p>

<pre><code>template&lt;typename T>
struct Converter {
  <a href="#adaptive-storage-desc"><span id="adaptive-storage">T source_;</span></a>
  Converter(T source) : source_(std::forward&lt;T>(source)) {}
  template&lt;typename U, <a href="#enable-if-desc"><span id="enable-if">decltype(static_cast&lt;U>(std::forward&lt;T>(source_)), 1)=0</span></a>>
  /*<strong>implicit</strong>*/ operator U() {
    return static_cast&lt;U>(std::forward&lt;T>(source_));
  }
};
template&lt;typename T>
Converter&lt;T> convert(<a href="#rvalue-param-desc"><span id="rvalue-param">T&& source</span></a>) {
  return Converter&lt;T>(std::forward&lt;T>(source));
}</code></pre>

    <p>Where an explicit conversion is desired, the user needs to write
    <code>convert(ptr)</code> in a context that expects a particular type.</p>

    <p>It's worth calling out some features of this implementation:</p>

    <ul>
      <li id="rvalue-param-desc"><code>convert()</code> uses a <a
      href="#rvalue-param"><code>T&&</code> parameter</a> to deduce the
      rvalue/const-ness of the argument, and then saves that exact type into the
      returned <code>Converter</code> object.  This allows the
      <code>Converter</code> to perfectly forward the argument into the target
      explicit conversion.</li>

      <li id="adaptive-storage-desc"><p>The <code>Converter</code> object appears
      to <a href="#adaptive-storage">store the source object by value</a>, but
      because the deduced parameter is passed in, it actually adapts to the
      exact type of the argument.  If the argument was an lvalue reference,
      <code>source_</code> is an lvalue reference to <code>convert()</code>'s
      argument.  If the argument was an rvalue reference or temporary, it's
      moved into the <code>Converter</code>, and then moved again into the
      explicit conversion.  Implementations can optimize this into a single move
      by specializing <code>Converter</code> separately for lvalue and rvalue
      arguments.  Trying to capture an rvalue reference directly would make</p>

      <pre class="example"><code>auto c = convert(Temporary());</code></pre>

      <p>unsafe.</p></li>

      <li id="enable-if-desc"><p>The implicit conversion operator is <a
      href="#enable-if">removed from the overload set</a> if there's no explicit
      conversion to the requested type.  This allows overload resolution to work
      as expected:</p>

<pre class="example"><code>struct Explicit {};
struct Unrelated{};
struct Source {
  explicit operator Explicit() const;
};

void overloaded(Explicit);
void overloaded(Unrelated);

void test() {
  overloaded(convert(Source()));  // Selects overloaded(Explicit).
}</code></pre></li>

      <li>This implementation only works on single-argument explicit
      conversions.  It would be possible to extend it to take multiple
      arguments, for example to let users work around the explicit-ness of
      <code>tuple&lt;></code>'s constructor, but <a
      href="http://cplusplus.github.com/LWG/lwg-active.html#2051">LWG Issue
      2051</a> proposes fixing that problem by making <code>tuple&lt;></code>'s
      constructor implicit, and I don't know of many other use cases.  Further,
      <code>convert(arg1, arg2, arg3)</code> is more different from <code>{arg1,
      arg2, arg3}</code> than <code>convert(arg)</code> is from
      <code>arg</code>.  Therefore, I leave this possibility to a future
      extension.</li>
    </ul>

    <header><h2 id="examples">Examples</h2></header>
    <p>The example from c++std-ext-14038 is easily handled:</p>

    <pre class="example"><code>unique_ptr&lt;Shape> read_shape(int i)
{
  switch(i) {
  case 1: return unique_ptr&lt;Shape>(new Circle);
  case 2: return convert(new Triangle);
  }
}</code></pre>

    <p>The proposed <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3430.html">std::split()</a>
    function yields another use case.  We'd like the returned range to be less
    magic, so it's likely to be a simple range of <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html"><code>std::string_ref</code></a>,
    which is only explicitly convertible to <code>std::string</code>.  If users
    want to initialize a <code>vector&lt;string></code> from a
    <code>split()</code> call, and we adopt a range library like <a
    href="http://www.boost.org/libs/range">Boost.Range</a>, the constructors
    from <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3456.html">N3456</a>,
    and <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3418.pdf">generic
    lambdas</a>, they'd write something like:</p>

<pre class="example"><code>std::vector&lt;std::string> v =
    std::split(input) | <a href="http://www.boost.org/libs/range/doc/html/range/reference/adaptors/reference/transformed.html">transformed</a>([](auto s) std::string(s));</code></pre>

    <p>This isn't too bad, but <code>convert()</code> helps us shorten it for
    everything after the first use:</p>

<pre class="example"><code>auto converted = <a href="http://www.boost.org/libs/range/doc/html/range/reference/adaptors/reference/transformed.html">transformed</a>([](auto v) std::convert(v));  // Define once, globally.

std::vector&lt;std::string> v = std::split(input) | converted;</code></pre>
  </section>

  <hr/>

  <section class="wording">
    <header><h2 id="wording">Wording</h2></header>

    <p>Wording is relative to <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf">N3485</a>.</p>


    <h3>In the "Header &lt;utility> synopsis" in [utility], add:</h3>

    <pre><code>// [utility.convert] convert:
template &lt;class T> <var>see below</var> convert(T&& source);</code></pre>

    <h3>Add a sub-section under [utility] named "convert [utility.convert]"</h3>

    <pre><code>template &lt;class T> <var>see below</var> convert(T&& source);</code></pre>
    <div class="attributes">
      <p><i>Requires</i>: If <code>T&&</code> is an rvalue reference type, <code>T</code> shall be <code>MoveConstructible</code> ([moveconstructible]).</p>

      <p><i>Returns</i>: An object with a member of type <code>T</code> that is
      constructed from <code>forward&lt;T>(source)</code>.  For exposition only,
      this member is named <code><var>source_</var></code>.  [ Note: This
      member has reference type if <code>source</code> was passed an lvalue.  It
      only implies a move if <code>source</code> was passed an rvalue. -- end
      note ]</p>

      <p><i>Remarks</i>:</p>
      <ul>
        <li>The returned object shall be implicitly convertible to exactly the
        types that <code>T</code> is either implicitly or explicitly convertible
        to.</li>
        <li>The conversion to type <code>U</code> shall be implemented
        equivalently to
        <code>static_cast&lt;U>(std::forward&lt;T>(<var>source_</var>))</code>.</li>
        <li>The returned object shall be <code>CopyConstructible</code> if
        either <code>T</code> is an lvalue reference type or <code>T</code> is
        <code>CopyConstructible</code>.</li>
      </ul>
    </div>
  </section>
</body>
</html>
