<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
<title>Implicit Return Type</title>
<meta name="date" content="2016-02-05" />
<meta name="author" content="Matthew Woehlke (mwoehlke.floss&#64;gmail.com)" />
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="implicit-return-type">
<h1 class="title">Implicit Return Type</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">Document:</th><td class="field-body">P0224R0</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2016-02-05</td></tr>
<tr class="field"><th class="docinfo-name">Project:</th><td class="field-body">ISO/IEC JTC1 SC22 WG21 Programming Language C++</td>
</tr>
<tr class="field"><th class="docinfo-name">Audience:</th><td class="field-body">Evolution Working Group</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Matthew Woehlke (<a class="reference external" href="mailto:mwoehlke.floss&#64;gmail.com">mwoehlke.floss&#64;gmail.com</a>)</td></tr>
</tbody>
</table>
<style>
  html { color: black; background: white; }
  table.docinfo { margin: 2em 0; }
  .literal-block { background: #eee; border: 1px solid #ddd; padding: 0.5em; }
  .addition { color: #2c2; text-decoration: underline; }
  .removal { color: #e22; text-decoration: line-through; }
  .literal-block .literal-block { background: none; border: none; }
  .block-addition { background: #cfc; text-decoration: underline; }
</style><div class="section" id="abstract">
<h1><a class="toc-backref" href="#id1">Abstract</a></h1>
<p>This proposal recommends an enhancement to return type deduction to allow the return type of a function definition to be inferred from a previous declaration of the same.</p>
<p>(Note: references made to the existing draft standard are made against <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf">N4567</a>.)</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#abstract" id="id1">Abstract</a></li>
<li><a class="reference internal" href="#rationale" id="id2">Rationale</a></li>
<li><a class="reference internal" href="#proposal" id="id3">Proposal</a></li>
<li><a class="reference internal" href="#proposed-wording" id="id4">Proposed Wording</a></li>
<li><a class="reference internal" href="#interactions" id="id5">Interactions</a></li>
<li><a class="reference internal" href="#discussion" id="id6">Discussion</a><ul>
<li><a class="reference internal" href="#is-this-feature-dangerous" id="id7">Is this feature dangerous?</a></li>
<li><a class="reference internal" href="#what-about-template-return-types" id="id8">What about template return types?</a></li>
<li><a class="reference internal" href="#must-the-declaration-providing-the-concrete-type-be-the-first-declaration" id="id9">Must the declaration providing the concrete type be the first declaration?</a></li>
</ul>
</li>
<li><a class="reference internal" href="#acknowledgments" id="id10">Acknowledgments</a></li>
<li><a class="reference internal" href="#references" id="id11">References</a></li>
</ul>
</div>
</div>
<div class="section" id="rationale">
<h1><a class="toc-backref" href="#id2">Rationale</a></h1>
<p>The origin for this idea relates to multiple return values, and a desire to use anonymous structs to implement the same. This notion will be further explored in a different paper (for which this proposal would be a prerequisite). The obvious problem with anonymous struct returns involves separating the declaration of such a function from its definition; namely, how does one repeat the name of the return type? This lead to a more interesting — and obvious in retrospect — question: since C++ functions (excluding templates) cannot be overloaded by their return value, <strong>why is it necessary to repeat the return value at all?</strong></p>
<p>Even in the case of return types that can be named, it may be that repeating the type name is excessively verbose or otherwise undesirable. Some might even call this a violation of the <a class="reference external" href="https://en.wikipedia.org/wiki/Don't_repeat_yourself">Don't Repeat Yourself</a> principle, similar to some of the issues that <tt class="docutils literal">auto</tt> for variable declaration was introduced to solve. (On the flip side, one could see the ability to elide the return type as subject to many abuses, again in much the manner of <tt class="docutils literal">auto</tt>. However, many language features can be abused; this should not prevent the addition of a feature that would provide an important benefit when used correctly.)</p>
<p>We would be remiss not to note that this is already possible in simple cases using <tt class="docutils literal">decltype</tt> and a sample invocation of the function. However, while this may be adequate in simple cases, it is nevertheless needlessly verbose, and as the argument list grows longer, and/or gains arguments for which providing a legal value is non-trivial, it can quickly become unwieldy and unfeasible.</p>
</div>
<div class="section" id="proposal">
<h1><a class="toc-backref" href="#id3">Proposal</a></h1>
<p>Recent changes to the language have progressively relaxed the requirements for how return types are specified. We began with trailing return type specification, and have progressed to inferred return types in certain cases.</p>
<p>This proposal is to continue this direction by adding an additional use of <tt class="docutils literal">auto</tt> as a return specifier, meaning &quot;use the return type seen when this function was previously declared&quot;. The use of <tt class="docutils literal">auto</tt> as the return type specifier, with no trailing return type, and for a function that has been previously declared with a known return type, shall instruct the compiler to define the function using the return type from the previous declaration.</p>
<p>Naturally, &quot;previous declaration&quot; here means a declaration having the same name and argument list. This, for example, would remain illegal:</p>
<pre class="code c++ literal-block">
<span class="keyword type">int</span> <span class="name function">foo</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">);</span>
<span class="keyword type">float</span> <span class="name function">foo</span><span class="punctuation">(</span><span class="keyword type">float</span><span class="punctuation">);</span>

<span class="keyword">auto</span> <span class="name function">foo</span><span class="punctuation">(</span><span class="keyword type">double</span> <span class="name">input</span><span class="punctuation">)</span> <span class="comment single">// does not match any previous declaration
</span><span class="punctuation">{</span>
  <span class="punctuation">...</span>
  <span class="keyword">return</span> <span class="name">result</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
</pre>
</div>
<div class="section" id="proposed-wording">
<h1><a class="toc-backref" href="#id4">Proposed Wording</a></h1>
<p>(Proposed changes are specified relative <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf">N4567</a>.)</p>
<p>Add a new section to [dcl.spec.auto] (7.1.6.4) as follows:</p>
<div class="literal-block block-addition compound">
<p class="compound-first">When a function is declared or defined using <tt class="docutils literal">auto</tt> for the return type, and a previous declaration or definition having a concrete return type exists, the return type shall be inferred to be the previously seen concrete type.
[<em>Example:</em></p>
<pre class="compound-middle literal-block">
std::string f();
auto f(); // OK, return type is std::string
</pre>
<p class="compound-last">— <em>end example</em>]</p>
</div>
<p>Add a new section to [dcl.spec.auto] (7.1.6.4) as follows:</p>
<div class="literal-block block-addition compound">
<p class="compound-first">A template function redeclaration or specialization having a return type of <tt class="docutils literal">auto</tt> shall match a previous declaration (or definition) if the first such declaration had a concrete return type. If the first such declaration also had a return type of <tt class="docutils literal">auto</tt>, the declaration using return type deduction shall be matched instead.
[<em>Example:</em></p>
<pre class="compound-middle literal-block">
template &lt;typename T&gt; T g(T t) { return t; } // #1
template auto g(float); // matches #1

template &lt;typename T&gt; auto g(T t) { return t; } // #2
template &lt;typename T&gt; T g(T t) { return t; }
template auto g(float); // matches #2
</pre>
<p class="compound-last">— <em>end example</em>]</p>
</div>
</div>
<div class="section" id="interactions">
<h1><a class="toc-backref" href="#id5">Interactions</a></h1>
<p>The three major C++ compilers (GCC, clang, MSVC) all presently reject the use of <tt class="docutils literal">auto</tt> as a return type in the presence of a prior declaration of the same (non-template) function, even in the case that the deduced return type matches the prior declaration, although the resulting diagnostics vary (MSVC and clang refer to overloads differing only by return type, while GCC mentions an &quot;ambiguating new declaration&quot;). The case of template functions is more interesting: see <a class="reference internal" href="#what-about-template-return-types">What about template return types?</a>. We believe that only very obscure code would be affected by this change. (Affected code may further be impractical; that is, while such code could be written, it would not serve a useful purpose, and is thus unlikely to affect any code in actual use.)</p>
<p>This proposal does not make any changes to other existing language or library features. (Implementations, however, may wish to make use of it; doing so would be a non-breaking change, since the semantic meaning of the code would not be affected.)</p>
</div>
<div class="section" id="discussion">
<h1><a class="toc-backref" href="#id6">Discussion</a></h1>
<div class="section" id="is-this-feature-dangerous">
<h2><a class="toc-backref" href="#id7">Is this feature dangerous?</a></h2>
<p>Moritz Klammler noted that the effect of the following code may be unexpected:</p>
<pre class="code c++ literal-block">
<span class="keyword type">float</span> <span class="name function">foo</span><span class="punctuation">();</span>
<span class="keyword">auto</span> <span class="name function">foo</span><span class="punctuation">()</span> <span class="punctuation">{</span> <span class="keyword">return</span> <span class="literal number float">42.0</span><span class="punctuation">;</span> <span class="punctuation">}</span>
</pre>
<p>If the declaration and definition are in different source files, it can appear that the return type of <tt class="docutils literal">foo()</tt> is <tt class="docutils literal">double</tt> (deduced), when under this proposal, it is in fact <tt class="docutils literal">float</tt> (inferred).</p>
<p>In practice, we don't expect this to be a serious issue. The above example is overly simplified, to the point that we would not expect this feature to be used in such an instance (and even if so, compilers provide warnings for such conversions). In the same manner, modern C++ is more strict about potentially dangerous implicit conversions; in the case of modern <tt class="docutils literal">return</tt> statements using type-elided braced initializers, an unsafe construct in a context like that presented would not be allowed.</p>
<p>Nevertheless, one way of addressing this problem would be to use some other syntax; either using something other than <tt class="docutils literal">auto</tt> to request return type inference, or by adding (optional) syntax (e.g. a new contextual keyword) following the parameter list. While we do not oppose such alternatives, they delve into the well known challenge of Naming Things. A trailing contextual keyword — perhaps <tt class="docutils literal">inferred_return</tt> — seems the only solution that does not risk invalidating existing code.</p>
</div>
<div class="section" id="what-about-template-return-types">
<h2><a class="toc-backref" href="#id8">What about template return types?</a></h2>
<p>In C++14, the following code is legal and produces two distinct templates:</p>
<pre class="code c++ literal-block">
<span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">class</span> <span class="name class">T</span><span class="operator">&gt;</span> <span class="keyword type">int</span> <span class="name">foo</span><span class="punctuation">();</span>
<span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">class</span> <span class="name class">T</span><span class="operator">&gt;</span> <span class="keyword">auto</span> <span class="name">foo</span><span class="punctuation">();</span>
</pre>
<p>This obviously conflicts with the proposed feature. After discussion on <tt class="docutils literal"><span class="pre">std-proposals</span></tt>, it was decided that the proposed feature should take precedence in this case. It should also be noted that it is unclear how, or even if, the second function can be invoked according to the current rules of the language. (To this end, it may be desirable to simply forbid the opposite ordering. However, we feel that this would be better addressed separately, perhaps even as a DR.)</p>
</div>
<div class="section" id="must-the-declaration-providing-the-concrete-type-be-the-first-declaration">
<h2><a class="toc-backref" href="#id9">Must the declaration providing the concrete type be the first declaration?</a></h2>
<p>This question was originally brought up by Bengt Gustafsson. Specifically, for the sake of symmetry, it seems initially desirable to allow:</p>
<pre class="code c++ literal-block">
<span class="keyword type">int</span> <span class="name function">foo</span><span class="punctuation">();</span> <span class="comment single">// specified return type
</span><span class="keyword">auto</span> <span class="name function">foo</span><span class="punctuation">()</span> <span class="punctuation">{</span> <span class="keyword">return</span> <span class="literal number integer">42</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="comment single">// return type inferred from prior declaration
</span>
<span class="keyword">auto</span> <span class="name function">bar</span><span class="punctuation">();</span> <span class="comment single">// forward declaration, type not yet known
</span><span class="keyword type">int</span> <span class="name function">bar</span><span class="punctuation">();</span> <span class="comment single">// specify the return type as 'int'
</span><span class="keyword">auto</span> <span class="name function">bar</span><span class="punctuation">()</span> <span class="punctuation">{</span> <span class="keyword">return</span> <span class="literal number integer">0</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="comment single">// return type inferred from prior declaration
</span>
</pre>
<p>To that end, earlier drafts of the proposal included the following proposed change to [dcl.spec.auto]/13 (7.1.6.4.13):</p>
<div class="literal-block compound">
<p class="compound-first">Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall <span class="removal">also use that placeholder</span> <span class="addition">use either that placeholder or a compatible concrete type</span>, not a deduced type. <span class="addition">If the return type has previously been deduced, a declaration using a concrete type shall use the deduced type.</span>
[<em>Example:</em></p>
<pre class="compound-last literal-block">
auto f();
auto f() { return 42; } // return type is int
auto f(); // OK
<span class="removal">int f(); // error, cannot be overloaded with auto f()</span>
<span class="addition">int f(); // OK, deduced type is also int</span>
decltype(auto) f(); // error, auto and decltype(auto) don't match

<span class="addition">auto f(int);</span>
<span class="addition">int f(int); // OK, return type of f(int) is now int</span>
<span class="addition">float f(int); // error, redeclared with different return type</span>
</pre>
</div>
<p>However, upon further discussion, reservations were expressed, and the general consensus seems to be that it is okay for the first declaration to &quot;set in stone&quot; if the return type will be known (and possibly later inferred), or deduced. Accordingly, absent the above change:</p>
<pre class="code c++ literal-block">
<span class="keyword">auto</span> <span class="name function">bar</span><span class="punctuation">();</span>
<span class="keyword type">int</span> <span class="name function">bar</span><span class="punctuation">();</span> <span class="comment single">// error, violates [dcl.spec.auto]/13
</span><span class="keyword">auto</span> <span class="name function">bar</span><span class="punctuation">()</span> <span class="punctuation">{</span> <span class="keyword">return</span> <span class="literal number integer">0</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="comment single">// okay, but return type is deduced, not inferred
</span>
</pre>
</div>
</div>
<div class="section" id="acknowledgments">
<h1><a class="toc-backref" href="#id10">Acknowledgments</a></h1>
<p>We wish to thank everyone on the <tt class="docutils literal"><span class="pre">std-proposals</span></tt> forum, especially Bengt Gustafsson and Tim Song, for their valuable feedback and insights.</p>
</div>
<div class="section" id="references">
<h1><a class="toc-backref" href="#id11">References</a></h1>
<ul>
<li><p class="first"><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf">N4567</a> Working Draft, Standard for Programming Language C++</p>
<p><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf</a></p>
</li>
</ul>
<!-- .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. -->
<!-- kate: hl reStructuredText -->
</div>
</div>
</body>
</html>
