<!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=US-ASCII">

<!-- This should replace the style block once it is published somewhere accessible
  <link href="../../base_www/style.hinc" rel="stylesheet" type="text/css" />
-->

  <style type="text/css">

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

    p.example { margin-left: 2em; }
    pre.example { margin-left: 2em; }
    div.example { margin-left: 2em; }

    code.extract { background-color: #F5F6A2; }
    pre.extract { margin-left: 2em; background-color: #F5F6A2;
      border: 1px solid #E1E28E; }

    p.function { }
    .attribute { margin-left: 2em; }
    .attribute dt { float: left; font-style: italic;
      padding-right: 1ex; }
    .attribute dd { margin-left: 0em; }

    blockquote.std { color: #000000; background-color: #F1F1F1;
      border: 1px solid #D1D1D1;
      padding-left: 0.5em; padding-right: 0.5em; }
    blockquote.stddel { text-decoration: line-through;
      color: #000000; background-color: #FFEBFF;
      border: 1px solid #ECD7EC;
      padding-left: 0.5empadding-right: 0.5em; ; }

    blockquote.stdins { text-decoration: underline;
      color: #000000; background-color: #C8FFC8;
      border: 1px solid #B3EBB3; padding: 0.5em; }

    table { border: 1px solid black; border-spacing: 0px;
      margin-left: auto; margin-right: auto; }
    th { text-align: left; vertical-align: top;
      padding-left: 0.8em; border: none; }
    td { text-align: left; vertical-align: top;
      padding-left: 0.8em; border: none; }

    table.docinfo { border: none; border-spacing: 0px;
      margin-left: auto; margin-right: none; float: right; }

  </style>

  <title>Return type deduction for explicitly-defaulted and deleted special member functions</title>

</head>

<body>
  <table border="1" class="docinfo">
    <tr> <th>Doc. No.:</th> <td>N4309</td> </tr>
    <tr> <th>Date:</th>     <td>2014-11-17</td> </tr>
    <tr> <th>Project:</th>  <td>Programming Language C++, Evolution Working Group</td> </tr>
    <tr> <th>Reply To:</th> <td>Michael Price<br/>
                                &lt;<a href="mailto:michael.b.price.dev@gmail.com">michael.b.price.dev@gmail.com</a>&gt;</td> </tr>
  </table>

  <br/>
  <h1>Return type deduction for explicitly-defaulted and deleted special member functions</h1>

  <h2><a name="introduction">I. Introduction</a></h2>

  <p>
    Proposes to allow <code>auto</code> and <code>declspec(auto)</code>
    as the <em>type-specifiers</em> for the return type of explicitly-defaulted
    and deleted special member functions.  It seems this case was left out of
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html">N3638</a>.
  </p>

  <h2><a name="motivation">II. Motivation</a></h2>

  <p>
    Paragraph 7.1.6.4, clause 2 of the draft standard
    (<a href="http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/n4141.pdf">N4141</a>)
    states:
  </p>

  <blockquote class="std"><p>
    The placeholder type can appear with a function declarator in the
    <em>decl-specifier-seq</em>, <em>type-specifier-seq</em>,
    <em>conversion-function-id</em>, or <em>trailing-return-type</em>, in any
    context where such a declarator is valid. If the function declarator
    includes a <em>trailing-return-type</em> (8.3.5), that specifies the
    declared return type of the function. If the declared return type of the
    function contains a placeholder type, the return type of the function is
    deduced from <code>return</code> statements in the body of the function,
    if any.
  </p></blockquote>

  <p>
    This wording allows the usage of <code>auto</code> or <code>declspec(auto)</code>
    in a function definition, only if there is a trailing return type or a
    function body that contains at least one <code>return</code>
    statement that can be used to deduce the return type.  This proposal would
    allow the placeholder type-specifiers to be valid for special member functions
    that are explicitly-defaulted or deleted.
  </p>

  <pre class="example">
  <code>struct VersionOne
  {
      VersionOne() = default;
      ~VersionOne() = default;
      VersionOne(const VersionOne&amp;) = default;
      VersionOne(VersionOne&amp;&amp;) = default;
      VersionOne&amp; operator=(const VersionOne&amp;) = default;
      VersionOne&amp; operator=(VersionOne&amp;&amp;) = default;
  };

  // For some reason, the author decided that I wanted non-default
  // copy operations and thought it would be nice to throw in 'auto'.
  //
  struct VersionTwo
  {
      VersionTwo() = default;
      ~VersionTwo() = default;
      VersionTwo(const VersionTwo&amp;) { /* ... */ }
      VersionTwo(VersionTwo&amp;&amp;) = default;
      auto operator=(const VersionTwo&amp;) { /* ... */ return *this; }
      auto operator=(VersionTwo&amp;&amp;) = default;  // Currently an error!
  };</code>
  </pre>

  <h2><a name="specification">III. Technical Specification</a></h2>

  <p>
    This paper is looking for guidance on whether this feature should be pursued.
    It provides no wording.
  </p>

</body>
</html>
