<?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.12: http://docutils.sourceforge.net/" />
<title>Implicit Return Type and Allowing Anonymous Types as Return Values</title>
<meta name="date" content="2017-02-03" />
<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-and-allowing-anonymous-types-as-return-values">
<h1 class="title">Implicit Return Type and Allowing Anonymous Types as Return Values</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">P0536R0</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2017-02-03</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; }
  p, li { text-align: justify; }
</style><div class="section" id="abstract">
<h1><a class="toc-backref" href="#id1">Abstract</a></h1>
<p>This proposal recommends the relaxing of [<a class="reference external" href="http://wg21.link/n4618#subsection.8.3.5">dcl.fct</a>]¶11; specifically, the prohibition of defining (anonymous) types as return values, and adding a mechanism that simplifies naming the return type of a previously declared function. These features were previously proposed separately, as <a class="reference external" href="http://wg21.link/p0222">P0222</a> and <a class="reference external" href="http://wg21.link/p0224">P0224</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="#interactions" id="id4">Interactions</a></li>
<li><a class="reference internal" href="#implementation-and-existing-practice" id="id5">Implementation and Existing Practice</a></li>
<li><a class="reference internal" href="#discussion" id="id6">Discussion</a><ul>
<li><a class="reference internal" href="#can-t-we-do-this-already" id="id7">Can't we do this already?</a></li>
<li><a class="reference internal" href="#should-we-allow-named-types-defined-as-return-types" id="id8">Should we allow <em>named</em> types defined as return types?</a></li>
<li><a class="reference internal" href="#isn-t-template-parsing-difficult" id="id9">Isn't template parsing difficult?</a></li>
<li><a class="reference internal" href="#is-decltype-return-dangerous" id="id10">Is <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> dangerous?</a></li>
<li><a class="reference internal" href="#what-about-defining-types-in-function-pointer-types" id="id11">What about defining types in function pointer types?</a></li>
<li><a class="reference internal" href="#what-about-defining-types-in-parameter-types" id="id12">What about defining types in parameter types?</a></li>
<li><a class="reference internal" href="#what-about-pass-through-of-return-values-having-equivalent-types" id="id13">What about &quot;pass-through&quot; of return values having equivalent types?</a></li>
<li><a class="reference internal" href="#does-this-conflicts-with-future-true-multiple-return-values" id="id14">Does this conflicts with future &quot;true&quot; multiple return values?</a></li>
<li><a class="reference internal" href="#what-about-deduced-return-types" id="id15">What about deduced return types?</a></li>
</ul>
</li>
<li><a class="reference internal" href="#future-directions" id="id16">Future Directions</a></li>
<li><a class="reference internal" href="#acknowledgments" id="id17">Acknowledgments</a></li>
<li><a class="reference internal" href="#references" id="id18">References</a></li>
</ul>
</div>
</div>
<div class="section" id="rationale">
<h1><a class="toc-backref" href="#id2">Rationale</a></h1>
<p>The concept of multiple return values is well known. At present, however, C++ lacks a good mechanism for implementing the same. <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">tuple</span></code> is considered clunky by many and, critically, creates sub-optimal API by virtue of the returned values being unnamed, forcing developers to rely on supplemental documentation to explain their purpose. Aggregates represent an improvement, being self-documenting, but the need to provide external definitions of the same is awkward and, worse, pollutes their corresponding namespace with entities that may be single use. Proposals such as <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4560.pdf">N4560</a> present a complicated mechanism for providing tagged (self-documenting) tuple-like types, which may be necessary in some cases, but still represent a non-trivial amount of complexity that ideally should not be required. <a class="reference external" href="http://wg21.link/p0341">P0341</a> presents a similar idea with tagged parameter packs as return values.</p>
<p>The addition of decomposition declarations in C++17 in particular represents a significant step toward support of multiple return values as first class citizens. This feature, along with other ongoing efforts to add first class support for &quot;product types&quot; and other efforts such as <a class="reference external" href="http://wg21.link/p0341">P0341</a> show an encouraging movement away from the traditional <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">pair</span></code> and <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">tuple</span></code> towards comparable concepts without requiring the explicit types. (We expect, however, that the standard template library types will remain useful for algorithms where the identity of the elements is unimportant, while it <em>is</em> important to be able to name at least the outer, if not complete, type. In that respect, we hypothesize that we may in the future see the ability to construct a <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">tuple</span></code> from any tuple-like, as also suggested in <a class="reference external" href="http://wg21.link/p0197">P0197</a>.)</p>
<p>On their own, however, these directions risk exacerbating the problem that this proposal aims to address. In particular, a concern with the notion of returning a parameter pack, as presented in <a class="reference external" href="http://wg21.link/p0341">P0341</a>, is that it opens a potential ABI can of worms. Moreover, parameter packs are not true types, and are subject to significant limitations, such as inability to make copies or pass them around as single entities, which are not shared by regular compound types. With generalized unpacking (<a class="reference external" href="http://wg21.link/p0535">P0535</a>), product types and parameter packs are effectively interchangeable, and returning a product type rather than a parameter pack leverages existing ABI and techniques, rather than introducing something entirely novel. The remaining issue is one of naming; naming things — in this case, return types, especially for one-off functions — is <em>hard</em>.</p>
<p>It has been suggested on multiple occasions that the optimal solution to the above issues is to return an anonymous <code class="cpp c++"><span class="keyword">struct</span></code>. This solves the problems of clutter and self-documentation, but runs afoul of a much worse issue; because the <code class="cpp c++"><span class="keyword">struct</span></code> is <em>anonymous</em>, it can be difficult to impossible to give its name a second time in order to separate the declaration and definition of the function that wishes to use it. This, however, leads to a more interesting question: <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 <code class="cpp c++"><span class="keyword">auto</span></code> 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 <code class="cpp c++"><span class="keyword">auto</span></code>. 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>While it is already possible in simple cases to use <code class="cpp c++"><span class="name">decltype</span></code> and a sample invocation of the function, this is needlessly verbose, and as the argument list grows longer, it can quickly become unwieldy.</p>
<p>While both these features have use on their own, they are nevertheless related, and we believe that presenting them together makes sense, and strengthens the case for each.</p>
</div>
<div class="section" id="proposal">
<h1><a class="toc-backref" href="#id3">Proposal</a></h1>
<p>We propose, first, to remove the restriction against (anonymous) types as return values:</p>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="punctuation">{</span> <span class="keyword type">int</span> <span class="name">id</span><span class="punctuation">;</span> <span class="keyword type">double</span> <span class="name">value</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="name">foo</span><span class="punctuation">()</span> <span class="punctuation">{</span> <span class="punctuation">...</span> <span class="punctuation">}</span>
</pre>
<p>We believe this can be accomplished largely by simply removing the prohibition in [<a class="reference external" href="http://wg21.link/n4618#subsection.8.3.5">dcl.fct</a>]¶11.</p>
<p>Second, we propose the addition of <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> to name — in a function signature — the return type of a previously declared function. This is consistent with recent changes to the language that have progressively relaxed the requirements for how return types are specified, and provides an optimal solution to the following problem:</p>
<pre class="code c++ literal-block">
<span class="comment single">// foo.h
</span><span class="keyword">struct</span> <span class="punctuation">{</span> <span class="keyword type">int</span> <span class="name">id</span><span class="punctuation">;</span> <span class="keyword type">double</span> <span class="name">value</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="name">foo</span><span class="punctuation">();</span>
</pre>
<p>How does one now provide an external definition for <code class="cpp c++"><span class="name">foo</span><span class="punctuation">()</span></code>? With our proposal, the solution is simple:</p>
<pre class="code c++ literal-block">
<span class="comment single">// foo.cpp
</span><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span> <span class="name">foo</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
  <span class="punctuation">...</span>
  <span class="keyword">return</span> <span class="punctuation">{</span> <span class="name">id</span><span class="punctuation">,</span> <span class="name">value</span> <span class="punctuation">};</span>
<span class="punctuation">}</span>
</pre>
<p>Naturally, &quot;previous declared&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="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span> <span class="name">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>
<p>The reasons to prohibit an anonymous struct defined as a return type have also been significantly mitigated. Constructing the return result is a non-issue, since the type name may now be elided, and the combination of <code class="cpp c++"><span class="keyword">auto</span></code> variable declarations, <code class="cpp c++"><span class="name">decltype</span></code>, and the proposed mechanism for naming the return type in a function signature permit implicit naming of the type where necessary. In short, the prohibition ([<a class="reference external" href="http://wg21.link/n4618#subsection.8.3.5">dcl.fct</a>]¶11) against defining types in return type specifications has become largely an artificial and arbitrary restriction which we propose to remove.</p>
<p>We additionally note that this prohibition is already not enforced by at least one major compiler (MSVC), and is enforced sporadically in others (see <a class="reference internal" href="#what-about-defining-types-in-function-pointer-types">What about defining types in function pointer types?</a>).</p>
</div>
<div class="section" id="interactions">
<h1><a class="toc-backref" href="#id4">Interactions</a></h1>
<p>Definition of a class-type as a return value type is currently ill-formed (although not universally enforced by existing major compilers), and the token sequence <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> is currently ill-formed. Accordingly, this change will not affect existing and conforming code, and may cause existing but non-conforming code to become conforming. This proposal does not make any changes to other existing language or library features; while conceivable that some library methods might benefit from the feature, such changes are potentially breaking, and no such changes are proposed at this time.</p>
</div>
<div class="section" id="implementation-and-existing-practice">
<h1><a class="toc-backref" href="#id5">Implementation and Existing Practice</a></h1>
<p>The proposed feature to allow defining types (including anonymous types) during return value specification is already at least partly implemented by MSVC and (to a lesser extent) GCC and ICC, and is also partly conforming to C++14. The trick shown in <a class="reference internal" href="#can-t-we-do-this-already">Can't we do this already?</a> as well as the curious, partial support in GCC and ICC (see <a class="reference internal" href="#what-about-defining-types-in-function-pointer-types">What about defining types in function pointer types?</a>) suggests that the existing prohibition may already be largely artificial, and that removing it would accordingly be a simple matter.</p>
<p>The proposed feature to allow <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> to name the return value has not, to our knowledge, been implemented, but given that compilers must already compare the return value when confronted with an initial declaration followed by subsequent redeclarations and/or a definition, we do not anticipate any implementation difficulties.</p>
</div>
<div class="section" id="discussion">
<h1><a class="toc-backref" href="#id6">Discussion</a></h1>
<div class="section" id="can-t-we-do-this-already">
<h2><a class="toc-backref" href="#id7">Can't we do this already?</a></h2>
<p>Astute observers may note that this is already legal (as of C++14):</p>
<pre class="code c++ literal-block">
<span class="keyword">auto</span> <span class="name function">f</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
  <span class="keyword">struct</span> <span class="punctuation">{</span> <span class="keyword type">int</span> <span class="name">x</span><span class="punctuation">,</span> <span class="name">y</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="name">result</span><span class="punctuation">;</span>
  <span class="comment single">// set values of result
</span>  <span class="keyword">return</span> <span class="name">result</span><span class="punctuation">;</span>
<span class="punctuation">}</span>
</pre>
<p>The critical problem with this, which we wish specifically to address, is that a (useful) forward declaration of such a function is not possible. We would see this as further justification for relaxing the existing prohibition, as proposed. (By &quot;useful&quot;, we mean particularly a forward declaration that allows the function to be called without a definition being seen, which is required to use the function across translation units without the function being defined in each.)</p>
</div>
<div class="section" id="should-we-allow-named-types-defined-as-return-types">
<h2><a class="toc-backref" href="#id8">Should we allow <em>named</em> types defined as return types?</a></h2>
<p>Allowing both named and anonymous types is a logical consequence of simply lifting the existing [<a class="reference external" href="http://wg21.link/n4618#subsection.8.3.5">dcl.fct</a>]¶11 prohibition as it is currently stated. It is also consistent, and already supported by MSVC:</p>
<pre class="code c++ literal-block">
<span class="comment single">// Equivalent to struct S { ... }; S foo();
</span><span class="keyword">struct</span> <span class="name">S</span> <span class="punctuation">{</span> <span class="punctuation">...</span> <span class="punctuation">}</span> <span class="name">foo</span><span class="punctuation">();</span>
</pre>
<p>That said, the value here is less obvious, and we would find it acceptable to permit definition of only anonymous types as return types.</p>
</div>
<div class="section" id="isn-t-template-parsing-difficult">
<h2><a class="toc-backref" href="#id9">Isn't template parsing difficult?</a></h2>
<p>Arthur O'Dwyer pointed out this interesting example:</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">struct</span> <span class="punctuation">{</span>
    <span class="keyword type">size_t</span> <span class="name">s</span><span class="punctuation">;</span>
<span class="punctuation">}</span> <span class="comment single">// Declaring a templated type, right?
</span><span class="name">what_size</span><span class="punctuation">(</span><span class="name">T</span> <span class="name">t</span><span class="punctuation">)</span> <span class="punctuation">{</span>
    <span class="keyword">return</span> <span class="punctuation">{</span><span class="keyword">sizeof</span><span class="punctuation">(</span><span class="name">t</span><span class="punctuation">)};</span>
<span class="punctuation">}</span>
</pre>
<p>It isn't obvious to the compiler, and not especially obvious to readers either, that this is a declaration of a templated function returning an anonymous type. Moreover, while the type itself is not templated, per-se, in effect it is, because (presumably?) each different instantiation of the function will have a distinct return type.</p>
<p>Since the primary motivation for this feature is for forward declarations of functions (per previous question, returning anonymous types is already possible with deduced return type), there are fewer use cases for the feature in conjunction with templated functions. As such, an easy cop-out is to retain the prohibition in these cases; we can always decide to lift it later.</p>
<p>An alternative (which may be worth considering for all cases) is to permit anonymous types only in trailing return type specifications, as follows:</p>
<pre class="code c++ literal-block">
<span class="keyword">auto</span> <span class="name">foo</span> <span class="operator">-&gt;</span> <span class="keyword">struct</span> <span class="punctuation">{</span> <span class="punctuation">...</span> <span class="punctuation">};</span>
<span class="keyword">template</span><span class="operator">&lt;</span><span class="punctuation">...</span><span class="operator">&gt;</span> <span class="keyword">auto</span> <span class="name">bar</span> <span class="operator">-&gt;</span> <span class="keyword">struct</span> <span class="punctuation">{</span> <span class="punctuation">...</span> <span class="punctuation">};</span>
</pre>
</div>
<div class="section" id="is-decltype-return-dangerous">
<h2><a class="toc-backref" href="#id10">Is <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> dangerous?</a></h2>
<p><a class="reference external" href="http://wg21.link/p0224">P0224</a> previously recommended overloading <code class="cpp c++"><span class="keyword">auto</span></code> as a mechanism for implicitly naming the return type given a prior declaration. While we believe this approach is feasible, there were some potential issues, which are discussed in <a class="reference external" href="http://wg21.link/p0224">P0224</a>. While we would happily accept the solution proposed by <a class="reference external" href="http://wg21.link/p0224">P0224</a>, we feel that <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> is less ambiguous, both to readers and to compilers. It is slightly more verbose than <code class="cpp c++"><span class="keyword">auto</span></code>, but not so much that we feel the added verbosity is an issue in those cases where we expect it to be used, and the extra verbosity may serve to deter &quot;frivolous&quot; use. Particularly, there is a clear distinction between inferred return values (the traditional use of <code class="cpp c++"><span class="keyword">auto</span></code> as a return type) and &quot;implied&quot; return values (that is, the use of <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> as an alternate spelling of a previously declared return type), which entirely avoids the issue this question, as it appears in <a class="reference external" href="http://wg21.link/p0224">P0224</a>, addressed.</p>
</div>
<div class="section" id="what-about-defining-types-in-function-pointer-types">
<h2><a class="toc-backref" href="#id11">What about defining types in function pointer types?</a></h2>
<p>An obvious consequence of relaxing [<a class="reference external" href="http://wg21.link/n4618#subsection.8.3.5">dcl.fct</a>]¶11 is the desire to permit function pointers which return an anonymous struct. For example:</p>
<pre class="code c++ literal-block">
<span class="comment single">// Declare a function pointer type which returns an anonymous struct
</span><span class="keyword">using</span> <span class="name">ReturnsAnonymousStruct</span> <span class="operator">=</span> <span class="keyword">struct</span> <span class="punctuation">{</span> <span class="keyword type">int</span> <span class="name">result</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="punctuation">(</span><span class="operator">*</span><span class="punctuation">)();</span>

<span class="comment single">// Define a function using the same
</span><span class="keyword type">int</span> <span class="name function">bar</span><span class="punctuation">(</span><span class="name">ReturnsAnonymousStruct</span> <span class="name">f</span><span class="punctuation">)</span> <span class="punctuation">{</span> <span class="keyword">return</span> <span class="punctuation">((</span><span class="operator">*</span><span class="name">f</span><span class="punctuation">)()).</span><span class="name">result</span><span class="punctuation">;</span> <span class="punctuation">}</span>

<span class="comment single">// Provide a mechanism to obtain the return type of a function
</span><span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">T</span><span class="operator">&gt;</span> <span class="keyword">struct</span> <span class="name">ReturnType</span><span class="punctuation">;</span>

<span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">T</span><span class="punctuation">,</span> <span class="keyword">typename</span><span class="punctuation">...</span> <span class="name">Args</span><span class="operator">&gt;</span>
<span class="keyword">struct</span> <span class="name">ReturnType</span><span class="operator">&lt;</span><span class="name">T</span> <span class="punctuation">(</span><span class="operator">*</span><span class="punctuation">)(</span><span class="name">Args</span><span class="punctuation">...)</span><span class="operator">&gt;</span>
<span class="punctuation">{</span>
    <span class="keyword">using</span> <span class="keyword type">result_t</span> <span class="operator">=</span> <span class="name">T</span><span class="punctuation">;</span>
<span class="punctuation">};</span>

<span class="comment single">// Declare a function that is a ReturnsAnonymousStruct
</span><span class="name">ReturnType</span><span class="operator">&lt;</span><span class="name">ReturnsAnonymousStruct</span><span class="operator">&gt;::</span><span class="keyword type">result_t</span> <span class="name">foo</span><span class="punctuation">()</span> <span class="punctuation">{</span> <span class="keyword">return</span> <span class="punctuation">{</span><span class="literal number integer">0</span><span class="punctuation">};</span> <span class="punctuation">}</span>

<span class="comment single">// Use the function
</span><span class="keyword type">int</span> <span class="name">main</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
    <span class="keyword">return</span> <span class="name">bar</span><span class="punctuation">(</span><span class="operator">&amp;</span><span class="name">foo</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
</pre>
<p>It is our opinion that the proposed changes are sufficient to allow the above. (In fact, this example is already accepted by both GCC and ICC, although it is rejected by clang per [<a class="reference external" href="http://wg21.link/n4618#subsection.8.3.5">dcl.fct</a>]¶11.) Accordingly, we feel that this proposal should be understood as intending to allow the above example and that additional wording changes to specify this behavior are not required at this time.</p>
</div>
<div class="section" id="what-about-defining-types-in-parameter-types">
<h2><a class="toc-backref" href="#id12">What about defining types in parameter types?</a></h2>
<p>An obvious follow-on question is, should we also lift the prohibition against types defined in parameter specifications? There have been suggestions floated to implement the much requested named parameters in something like this manner. However, there are significant (in our opinion) reasons to not address this, at least initially. First, it is widely contested that this is not an optimal solution to the problem (named parameters) in the first place. Second, it depends on named initializers, which have a behavior that may not match that desired for named parameters. Third, this proposal works largely because C++ forbids overloading on return type, which may be leveraged to eliminate any ambiguity as to the deduction of the actual type of <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code>. This is not the case for parameters; the ability to overload functions would make a similar change for parameters much more complicated.</p>
<p>While we do not wish to categorically rule out future changes in this direction, we feel that it is not appropriate for this proposal to attempt to address these issues.</p>
</div>
<div class="section" id="what-about-pass-through-of-return-values-having-equivalent-types">
<h2><a class="toc-backref" href="#id13">What about &quot;pass-through&quot; of return values having equivalent types?</a></h2>
<p>Another question that has come up is if something like this should be allowed:</p>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="punctuation">{</span> <span class="keyword type">int</span> <span class="name">result</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="name">foo</span><span class="punctuation">()</span> <span class="punctuation">{</span> <span class="punctuation">...</span> <span class="punctuation">}</span>
<span class="keyword">struct</span> <span class="punctuation">{</span> <span class="keyword type">int</span> <span class="name">result</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="name">bar</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
  <span class="keyword">return</span> <span class="name">foo</span><span class="punctuation">();</span>
<span class="punctuation">}</span>
</pre>
<p>Specifically, others have expressed an interest in treating layout-compatible types as equivalent (or at least, implicitly convertible), particularly in the context of return values as in the above example.</p>
<p>Under the current rules (plus relaxed [<a class="reference external" href="http://wg21.link/n4618#subsection.8.3.5">dcl.fct</a>]¶11), these two definitions have different return types which are not convertible. It is our opinion that the rules making these types different are in fact correct and desirable, and this proposal specifically does <em>not</em> include any changes which would make the types compatible. That said, we note that <a class="reference external" href="http://wg21.link/p0535">P0535</a> provides a ready solution to this problem:</p>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="punctuation">{</span> <span class="keyword type">int</span> <span class="name">result</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="name">bar</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
  <span class="keyword">return</span> <span class="punctuation">{</span> <span class="punctuation">[</span><span class="operator">:</span><span class="punctuation">]</span><span class="name">foo</span><span class="punctuation">()...</span> <span class="punctuation">};</span>
<span class="punctuation">}</span>
</pre>
</div>
<div class="section" id="does-this-conflicts-with-future-true-multiple-return-values">
<h2><a class="toc-backref" href="#id14">Does this conflicts with future &quot;true&quot; multiple return values?</a></h2>
<p>There has been some discussion of &quot;true&quot; multiple return values, in particular with respect to RVO and similar issues. In particular, some features proposed by <a class="reference external" href="http://wg21.link/p0341">P0341</a> are very much in this vein. A point that bears consideration is if moving down the path of using anonymous (or not) structs for multiple return values will &quot;paint us into a corner&quot; where future optimization potential is prematurely eliminated.</p>
<p>It is our hope that these issues can be addressed with existing compound types (which will have further reaching benefit). Moreover, as previously stated, the use of compound types for multiple return values uses existing techniques and is well understood, whereas introducing &quot;first class&quot; multiple return values introduces questions of ABI and other issues.</p>
</div>
<div class="section" id="what-about-deduced-return-types">
<h2><a class="toc-backref" href="#id15">What about deduced return types?</a></h2>
<p>The relaxation of [<a class="reference external" href="http://wg21.link/n4618#subsection.8.3.5">dcl.fct</a>]¶11 is not intended to extend to deduction of new types via deduced return types. In light of <a class="reference external" href="http://wg21.link/p0329">P0329</a>, we might imagine a further extension that would allow us to lift this restriction:</p>
<pre class="code c++ literal-block">
<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="punctuation">{</span> <span class="punctuation">.</span><span class="name">x</span> <span class="operator">=</span> <span class="literal number integer">3</span><span class="punctuation">,</span> <span class="punctuation">.</span><span class="name">y</span> <span class="operator">=</span> <span class="literal number integer">2</span> <span class="punctuation">};</span> <span class="comment single">// deduce: struct { int x, y; }
</span><span class="punctuation">}</span>
</pre>
<p>However, we have reservations about allowing this, and do not at this time propose that this example would be well-formed.</p>
</div>
</div>
<div class="section" id="future-directions">
<h1><a class="toc-backref" href="#id16">Future Directions</a></h1>
<p>In the <a class="reference internal" href="#discussion">Discussion</a> section above, we presented a utility for extracting the return type from a function pointer type. The facility as presented has significant limitations; namely, it does not work on member functions and the several variations (e.g. CV-qualification) which apply to the same. We do not here propose a standard library implementation of this facility, which presumably would cover these cases, however there is room to imagine that such a facility could be useful, especially if the proposals we present here are adopted. (David Krauss points out that <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">reference_wrapper</span></code> can be used to similar effect... on <em>some</em> compilers. However, imperfect portability and the disparity between intended function and use for this result suggest that this is not the optimal facility for the problem.)</p>
<p>Another consideration that seems likely to come up is if we should further simplify the syntax for returning multiple values (conceivably, this could apply to both anonymous structs and to <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">pair</span></code> / <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">tuple</span></code>). Some have suggested allowing that the <code class="cpp c++"><span class="keyword">struct</span></code> keyword may be omitted. In light of <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0151r0.pdf">P0151</a> and <a class="reference external" href="http://wg21.link/p0341">P0341</a>, we can conceive that allowing the syntax <code class="cpp c++"><span class="operator">&lt;</span><span class="keyword type">int</span> <span class="name">x</span><span class="punctuation">,</span> <span class="keyword type">double</span> <span class="name">y</span><span class="operator">&gt;</span> <span class="name">foo</span><span class="punctuation">()</span></code> might be interesting (in contrast to <a class="reference external" href="http://wg21.link/p0341">P0341</a>, we would suggest that this be shorthand for <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">tuple</span></code> if the names are omitted). At this time, we prefer to focus on the feature here presented rather than risk overextending the reach of this proposal. However, if this proposal is accepted, it represents an obvious first step to considering such features in the future.</p>
<p>A final consideration is the extension of <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> to allow use within a function body. At the time of writing, we are not aware of a proposal to do so, although the idea has been floated on numerous occasions. We would hope to see such an addition, which can be orthogonal to this proposal, in the near future. (This also serves as an additional argument for using <code class="cpp c++"><span class="name">decltype</span><span class="punctuation">(</span><span class="keyword">return</span><span class="punctuation">)</span></code> to name the return value rather than <code class="cpp c++"><span class="keyword">auto</span></code>.)</p>
</div>
<div class="section" id="acknowledgments">
<h1><a class="toc-backref" href="#id17">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, Arthur O'Dwyer and R. &quot;Tim&quot; Song, for their valuable feedback and insights.</p>
</div>
<div class="section" id="references">
<h1><a class="toc-backref" href="#id18">References</a></h1>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/n4618">N4618</a> Working Draft, Standard for Programming Language C++</p>
<p><a class="reference external" href="http://wg21.link/n4618">http://wg21.link/n4618</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4560.pdf">N4560</a> Extensions for Ranges</p>
<p><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4560.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4560.pdf</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0151r0.pdf">P0151</a> Proposal of Multi-Declarators (aka Structured Bindings)</p>
<p><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0151r0.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0151r0.pdf</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/p0197">P0197</a> Default Tuple-like Access</p>
<p><a class="reference external" href="http://wg21.link/p0197">http://wg21.link/p0197</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/p0222">P0222</a> Allowing Anonymous Structs as Return Values</p>
<p><a class="reference external" href="http://wg21.link/p0224">http://wg21.link/p0224</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/p0224">P0224</a> Implicit Return Type</p>
<p><a class="reference external" href="http://wg21.link/p0224">http://wg21.link/p0224</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/p0329">P0329</a> Designated Initializer Wording</p>
<p><a class="reference external" href="http://wg21.link/p0329">http://wg21.link/p0329</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/p0341">P0341</a> Parameter Packs Outside of Templates</p>
<p><a class="reference external" href="http://wg21.link/p0341">http://wg21.link/p0341</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/p0535">P0535</a> Generalized Unpacking and Parameter Pack Slicing</p>
<p><a class="reference external" href="http://wg21.link/p0535">http://wg21.link/p0535</a></p>
</li>
</ul>
<!-- .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. -->
<!-- .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. -->
<!-- kate: hl reStructuredText -->
</div>
</div>
</body>
</html>
