<?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>P0018r00 : Lambda Capture of *this by Value</title>
<meta name="author" content="H. Carter Edwards" />
<meta name="author" content="Christian Trott" />
<meta name="author" content="Hal Finkel" />
<meta name="author" content="Jim Reus" />
<meta name="author" content="Robin Maffeo" />
<meta name="author" content="Ben Sander" />
<meta name="date" content="2015-09-23" />
<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="p0018r00-lambda-capture-of-this-by-value">
<h1 class="title">P0018r00 : Lambda Capture of *this by Value</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>H. Carter Edwards</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:hcedwar&#64;sandia.gov">hcedwar&#64;sandia.gov</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Christian Trott</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:crtrott&#64;sandia.gov">crtrott&#64;sandia.gov</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Hal Finkel</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:hfinkel&#64;anl.gov">hfinkel&#64;anl.gov</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Jim Reus</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:reus1&#64;llnl.gov">reus1&#64;llnl.gov</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Robin Maffeo</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:robin.maffeo&#64;amd.com">robin.maffeo&#64;amd.com</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Ben Sander</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:ben.sander&#64;amd.com">ben.sander&#64;amd.com</a></td></tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">P0018</td>
</tr>
<tr><th class="docinfo-name">Version:</th>
<td>00</td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2015-09-23</td></tr>
<tr class="field"><th class="docinfo-name">URL:</th><td class="field-body"><a class="reference external" href="https://github.com/kokkos/ISO-CPP-Papers/blob/master/P0018.rst">https://github.com/kokkos/ISO-CPP-Papers/blob/master/P0018.rst</a></td>
</tr>
<tr class="field"><th class="docinfo-name">WG21:</th><td class="field-body">Evolution Working Group (EWG)</td>
</tr>
<tr class="field"><th class="docinfo-name">WG21:</th><td class="field-body">Concurrency and Parallelism Study Group (SG1)</td>
</tr>
</tbody>
</table>
<div class="section" id="issue">
<h1>1&nbsp;&nbsp;&nbsp;Issue</h1>
<p>Lambda expressions declared within a non-static member function explicilty
or implicitly captures <strong>this</strong> to access to member variables of <strong>this</strong>.
Both capture-by-reference <strong>[&amp;]</strong> and capture-by-value <strong>[=]</strong> implicitly
capture the <strong>this</strong> pointer, therefore member variables are always accessed
by reference via <strong>this</strong>.
Thus the capture-default has no effect on the capture of <strong>this</strong>.</p>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="name">S</span> <span class="punctuation">{</span>
  <span class="keyword type">int</span> <span class="name">x</span> <span class="punctuation">;</span>
  <span class="keyword type">void</span> <span class="name function">f</span><span class="punctuation">()</span> <span class="punctuation">{</span>
    <span class="comment single">// The following lambda captures are currently identical
</span>    <span class="keyword">auto</span> <span class="name">a</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">&amp;</span><span class="punctuation">]()</span> <span class="punctuation">{</span> <span class="name">x</span> <span class="operator">=</span> <span class="literal number integer">42</span> <span class="punctuation">;</span> <span class="punctuation">}</span> <span class="comment single">// OK: transformed to (*this).x
</span>    <span class="keyword">auto</span> <span class="name">b</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">]()</span> <span class="punctuation">{</span> <span class="name">x</span> <span class="operator">=</span> <span class="literal number integer">43</span> <span class="punctuation">;</span> <span class="punctuation">}</span> <span class="comment single">// OK: transformed to (*this).x
</span>    <span class="name">a</span><span class="punctuation">();</span>
    <span class="name">assert</span><span class="punctuation">(</span> <span class="name">x</span> <span class="operator">==</span> <span class="literal number integer">42</span> <span class="punctuation">);</span>
    <span class="name">b</span><span class="punctuation">();</span>
    <span class="name">assert</span><span class="punctuation">(</span> <span class="name">x</span> <span class="operator">==</span> <span class="literal number integer">43</span> <span class="punctuation">);</span>
  <span class="punctuation">}</span>
<span class="punctuation">};</span>
</pre>
<!-- /* -->
</div>
<div class="section" id="motivations-for-lambda-capture-of-this-by-value">
<h1>2&nbsp;&nbsp;&nbsp;Motivations for lambda capture of <strong>*this</strong> by Value</h1>
<p>Truly capturing <strong>*this</strong> by value allows an implicitly declared
closure to be copied before invoking the closure's functon.</p>
<div class="section" id="asynchronous-dispatch-of-lambda">
<h2>2.1&nbsp;&nbsp;&nbsp;Asynchronous dispatch of lambda</h2>
<p>Asynchronous dispatch of closures a cornerstone of parallelism
and concurrency.</p>
<p>When a lambda is asynchronously dispatched from within a
non-static member function, via <strong>std::async</strong>
or other concurrency / parallelism dispatch mechanism,
the enclosing <strong>*this</strong> class <em>cannot</em> be captured by value.
Thus when the <strong>future</strong> (or other handle) to the dispatched lambda
outlives the originating class the lambda's captured <strong>this</strong>
pointer is invalid.</p>
<pre class="code c++ literal-block">
<span class="keyword">class</span> <span class="name class">Work</span> <span class="punctuation">{</span>
<span class="keyword">private</span><span class="operator">:</span>
  <span class="keyword type">int</span> <span class="name">value</span> <span class="punctuation">;</span>
<span class="keyword">public</span><span class="operator">:</span>
  <span class="name">Work</span><span class="punctuation">()</span> <span class="operator">:</span> <span class="name">value</span><span class="punctuation">(</span><span class="literal number integer">42</span><span class="punctuation">)</span> <span class="punctuation">{}</span>
  <span class="name">std</span><span class="operator">::</span><span class="name">future</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span> <span class="name">spawn</span><span class="punctuation">()</span>
    <span class="punctuation">{</span> <span class="keyword">return</span> <span class="name">std</span><span class="operator">::</span><span class="name">async</span><span class="punctuation">(</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">]()</span><span class="operator">-&gt;</span><span class="keyword type">int</span><span class="punctuation">{</span> <span class="keyword">return</span> <span class="name">value</span> <span class="punctuation">;</span> <span class="punctuation">});</span> <span class="punctuation">}</span>
<span class="punctuation">};</span>

<span class="name">std</span><span class="operator">::</span><span class="name">future</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span> <span class="name">foo</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
  <span class="name">Work</span> <span class="name">tmp</span> <span class="punctuation">;</span>
  <span class="keyword">return</span> <span class="name">tmp</span><span class="punctuation">.</span><span class="name">spawn</span><span class="punctuation">();</span>
  <span class="comment single">// The closure associated with the returned future
</span>  <span class="comment single">// has an implicit this pointer that is invalid.
</span><span class="punctuation">}</span>

<span class="keyword type">int</span> <span class="name">main</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
  <span class="name">std</span><span class="operator">::</span><span class="name">future</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span> <span class="name">f</span> <span class="operator">=</span> <span class="name">foo</span><span class="punctuation">();</span>
  <span class="name">f</span><span class="punctuation">.</span><span class="name">wait</span><span class="punctuation">();</span>
  <span class="comment single">// The following fails due to the
</span>  <span class="comment single">// originating class having been destroyed
</span>  <span class="name">assert</span><span class="punctuation">(</span> <span class="literal number integer">42</span> <span class="operator">==</span> <span class="name">f</span><span class="punctuation">.</span><span class="name">get</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>
</pre>
<!--  -->
</div>
<div class="section" id="dispatching-asynchronous-closures-to-data">
<h2>2.2&nbsp;&nbsp;&nbsp;Dispatching asynchronous closures to data</h2>
<p>Current and future hardware architectures
specifically targeting parallelism and concurrency have
heterogeneous memory systems.
For example, NUMA regions, attached accelerator memory, and
processing-in-memory (PIM) stacks.
In these architectures it will often result in signficantly
improved performance if the closure is copied to the
data upon which it operates, as opposed to moving
the data to and from the closure.</p>
<p>For example, parallel execution of a closure on large data
spanning NUMA regions will be more performant if a copy
of that closure residing in the same NUMA region acts
upon that data.
If true a (self-contained) capture-by-value lambda closure
were given to a parallel dispatch, such as in the
parallelism technical specification, then the library could
create copies of that closure within each NUMA region to improve
data locality for the parallel computation.
For another example, a closure dispatched to an attached accelerator
with separate memory must be copied to the accelerator's
memory before execution can occur.
Thus current and future architectures <em>require</em> the capability
to copy closures to data.</p>
</div>
<div class="section" id="onerous-and-error-prone-work-around">
<h2>2.3&nbsp;&nbsp;&nbsp;Onerous and error-prone work-around</h2>
<p>A potential work-around for this deficiency is to explicitly
capture a copy the originating class.</p>
<pre class="code c++ literal-block">
<span class="keyword">class</span> <span class="name class">Work</span> <span class="punctuation">{</span>
<span class="keyword">private</span><span class="operator">:</span>
  <span class="keyword type">int</span> <span class="name">value</span> <span class="punctuation">;</span>
<span class="keyword">public</span><span class="operator">:</span>
  <span class="name">Work</span><span class="punctuation">()</span> <span class="operator">:</span> <span class="name">value</span><span class="punctuation">(</span><span class="literal number integer">42</span><span class="punctuation">)</span> <span class="punctuation">{}</span>
  <span class="name">std</span><span class="operator">::</span><span class="name">future</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span> <span class="name">spawn</span><span class="punctuation">()</span>
    <span class="punctuation">{</span>
      <span class="keyword">return</span> <span class="name">std</span><span class="operator">::</span><span class="name">async</span><span class="punctuation">(</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">,</span><span class="name">tmp</span><span class="operator">=*</span><span class="keyword">this</span><span class="punctuation">]()</span><span class="operator">-&gt;</span><span class="keyword type">int</span><span class="punctuation">{</span> <span class="keyword">return</span> <span class="name">tmp</span><span class="punctuation">.</span><span class="name">value</span> <span class="punctuation">;</span> <span class="punctuation">});</span>
    <span class="punctuation">}</span>
<span class="punctuation">};</span>
</pre>
<!--  -->
<p>This work-around has two liabilities.
First, the <strong>this</strong> pointer is also captured which provides
a significant opportunity to erroneously reference a
<strong>this-&gt;</strong> member instead of a <strong>tmp.</strong> member.
Second, it is onerous and counter-productive
to the introduction of asynchronously dispatched lambda expressions
within existing code.
Consder the case of replacing a <strong>for</strong> loop within a
non-static member function with a <em>parallel for each</em> construct
as in the parallelism technical specification.</p>
<pre class="code c++ literal-block">
<span class="keyword">class</span> <span class="name class">Work</span> <span class="punctuation">{</span>
<span class="keyword">public</span><span class="operator">:</span>
  <span class="keyword type">void</span> <span class="name">do_something</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="punctuation">{</span>
    <span class="comment single">// for ( int i = 0 ; i &lt; N ; ++i )
</span>    <span class="name">foreach</span><span class="punctuation">(</span> <span class="name">Parallel</span> <span class="punctuation">,</span> <span class="literal number integer">0</span> <span class="punctuation">,</span> <span class="name">N</span> <span class="punctuation">,</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">,</span><span class="name">tmp</span><span class="operator">=*</span><span class="keyword">this</span><span class="punctuation">](</span> <span class="keyword type">int</span> <span class="name">i</span> <span class="punctuation">)</span>
    <span class="punctuation">{</span>
      <span class="comment single">// A modestly long loop body where
</span>      <span class="comment single">// every reference to a member must be modified
</span>      <span class="comment single">// for qualification with 'tmp.'
</span>      <span class="comment single">// Any mistaken omissions will silently fail
</span>      <span class="comment single">// as references via 'this-&gt;'.
</span>    <span class="punctuation">}</span>
    <span class="punctuation">);</span>
  <span class="punctuation">}</span>
<span class="punctuation">};</span>
</pre>
<!--  -->
<p>In this example every reference to a member
in the pre-existing code must be modified to
add the <strong>tmp.</strong> qualification.
This onerous process must be repeated throughout
an existing code base.
A true lambda capture of <strong>*this</strong> would eliminate
such an onerous and silent-error-prone process of
injecting parallelism
and concurrency into an large, existing code base.</p>
</div>
<div class="section" id="safety-and-productivity-in-parallelism-and-concurrency">
<h2>2.4&nbsp;&nbsp;&nbsp;Safety and productivity in parallelism and concurrency</h2>
<p>As currently specified integration of lambda and concurrency
capabilities is perilous, as demonstrated by the previous <strong>Work</strong> example.
A lambda generated within a non-static member function <em>cannot</em>
be a true (self-contained) closure and therefore cannot reliably
be used with an asynchronous dispatch.</p>
<p>Lambda capability is a significant boon to productivity,
especially when parallel or concurrent closures can be
defined with lambdas as opposed to manually generated functors.
If the capability to capture <strong>*this</strong> by value
is not enabled then the productivity benefits of lambdas
cannot be fully realized in the parallelism and concurrency domain.</p>
</div>
</div>
<div class="section" id="semantics-of-lamda-capture-of-this-by-value">
<h1>3&nbsp;&nbsp;&nbsp;Semantics of Lamda Capture of <strong>*this</strong> by value</h1>
<p>Lambda captures of <strong>*this</strong> by value within a non-static member function is as if:</p>
<ul class="simple">
<li>the implicitly generated closure object type is derived from the type of <strong>*this</strong>,</li>
<li>the closure object type is declared a <strong>friend</strong> of the of the type of <strong>*this</strong>,</li>
<li>the closure object type has <strong>using</strong> statements for all members of the type of <strong>*this</strong> that are accessed within the lambda expression, and</li>
<li>the <strong>*this</strong> object is copy constructed into the closure object.</li>
</ul>
<p>Requires: The type of <strong>*this</strong> to be copy constructable.</p>
<p>Requires: Lambda capture of <strong>*this</strong> by value does not occur within a copy constructor, or function invoked by a copy constructor, as this would result in a infinite recursion of the copy constructor.  This requirement would also be applicable to the onerous work-around.</p>
</div>
<div class="section" id="resolution-option-1-correct-lambda-capture-by-value">
<h1>4&nbsp;&nbsp;&nbsp;Resolution Option #1: Correct Lambda Capture-by-value <strong>[=]</strong></h1>
<p>The semantically consistent resolution is for the <em>capture-default</em> <strong>[=]</strong>
to capture <strong>*this</strong> by value for lambda expressions within a non-static
member function.
The <em>capture-default</em> <strong>[&amp;]</strong> within a non-static member function
conforms to the current capture specification for <strong>this</strong>.</p>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="name">S</span> <span class="punctuation">{</span>
  <span class="keyword type">int</span> <span class="name">x</span> <span class="punctuation">;</span>
  <span class="keyword type">void</span> <span class="name function">f</span><span class="punctuation">()</span> <span class="punctuation">{</span>
    <span class="keyword">auto</span> <span class="name">a</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">&amp;</span><span class="punctuation">]()</span> <span class="punctuation">{</span> <span class="name">x</span> <span class="operator">=</span> <span class="literal number integer">42</span> <span class="punctuation">;</span> <span class="punctuation">}</span> <span class="comment single">// OK: transformed to (*this).x
</span>    <span class="keyword">auto</span> <span class="name">b</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">]()</span> <span class="keyword">mutable</span> <span class="punctuation">{</span> <span class="name">x</span> <span class="operator">=</span> <span class="literal number integer">42</span> <span class="punctuation">;</span> <span class="punctuation">}</span> <span class="comment single">// Modifying copy of x
</span>
    <span class="keyword">auto</span> <span class="name">c</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">]()</span> <span class="punctuation">{</span> <span class="name">x</span> <span class="operator">=</span> <span class="literal number integer">42</span> <span class="punctuation">;</span> <span class="punctuation">}</span> <span class="comment single">// Error: captured copy of '*this'
</span>                                <span class="comment single">// and lambda function is 'const'
</span>  <span class="punctuation">}</span>
<span class="punctuation">};</span>
</pre>
<!-- /* -->
<p>This resolution would correct lambda capture semantics;
however, it is likely to break existing code.
As such we propose the following solution.</p>
</div>
<div class="section" id="resolution-option-2-add-true-lambda-capture-by-value">
<h1>5&nbsp;&nbsp;&nbsp;Resolution Option #2: Add True Lambda Capture-by-value <strong>[*]</strong></h1>
<p>Given that the semantically consistent resolution would break
current standard behavior, a new capture mechanism is necessary
to provide semantically consistent capture-by-value semantics for
lambda expressions within non-status member functions.</p>
<p>Extend the <em>capture-default</em> and <em>simple-capture</em> to include:</p>
<blockquote>
<div class="line-block">
<div class="line"><em>capture-default</em>:</div>
<div class="line-block">
<div class="line">&amp;</div>
<div class="line">=</div>
<div class="line">*</div>
</div>
<div class="line"><em>simple-capture</em>:</div>
<div class="line-block">
<div class="line"><em>identifier</em></div>
<div class="line">&amp; <em>identifier</em></div>
<div class="line"><strong>this</strong></div>
<div class="line"><strong>*this</strong></div>
</div>
</div>
</blockquote>
<p>The <em>simple-capture</em> <strong>*this</strong> declares that <strong>*this</strong>
is to be captured by value.
The <em>capture-default</em> <strong>[*]</strong> declares that the default capture
is by value, including <strong>*this</strong> if the lambda
expression appears within a non-static member function.
Outside of a non-static member function the <em>capture-default</em> <strong>[*]</strong>
is identical to the <em>capture-default</em> <strong>[=]</strong>.</p>
<div class="section" id="nested-lambda-capture">
<h2>5.1&nbsp;&nbsp;&nbsp;Nested lambda capture</h2>
<p>A new capture mechanism introduces a introduces new capture interaction.
For non-<strong>*this</strong> captures the interactions remain unchanged.
When <strong>*this</strong> is captured by value via <strong>[*]</strong> nested captures
of <strong>this</strong> refer to the enclosing copy of <strong>*this</strong>.</p>
<pre class="code c++ literal-block">
<span class="keyword type">void</span> <span class="name">Work</span><span class="operator">::</span><span class="name">foo</span><span class="punctuation">()</span>
<span class="punctuation">{</span>
  <span class="keyword">auto</span> <span class="name">x</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">*</span><span class="punctuation">]()</span> <span class="punctuation">{</span> <span class="comment single">// *this is captured by value
</span>    <span class="keyword">auto</span> <span class="name">y</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">&amp;</span><span class="punctuation">]()</span> <span class="punctuation">{</span>
      <span class="comment single">// refer to the copy of Work contained in 'x'
</span>      <span class="comment single">// does not refer to the original enclosing 'this'
</span>      <span class="keyword">this</span><span class="operator">-&gt;</span><span class="name">value</span>
    <span class="punctuation">};</span>
    <span class="keyword">auto</span> <span class="name">z</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">]()</span> <span class="punctuation">{</span>
      <span class="comment single">// refer to the copy of Work contained in 'x'
</span>      <span class="comment single">// does not refer to the original enclosing 'this'
</span>      <span class="keyword">this</span><span class="operator">-&gt;</span><span class="name">value</span>
    <span class="punctuation">};</span>
  <span class="punctuation">};</span>
<span class="punctuation">}</span>
</pre>
<!--  -->
</div>
<div class="section" id="updated-example">
<h2>5.2&nbsp;&nbsp;&nbsp;Updated example</h2>
<p>With true lambda capture-by-value the earlier example
can have the correct behavior by generating a complete closure.</p>
<pre class="code c++ literal-block">
<span class="keyword">class</span> <span class="name class">Work</span> <span class="punctuation">{</span>
<span class="keyword">private</span><span class="operator">:</span>
  <span class="keyword type">int</span> <span class="name">value</span> <span class="punctuation">;</span>
<span class="keyword">public</span><span class="operator">:</span>
  <span class="name">Work</span><span class="punctuation">()</span> <span class="operator">:</span> <span class="name">value</span><span class="punctuation">(</span><span class="literal number integer">42</span><span class="punctuation">)</span> <span class="punctuation">{}</span>

  <span class="name">std</span><span class="operator">::</span><span class="name">future</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span> <span class="name">spawn</span><span class="punctuation">()</span>
    <span class="comment single">// Capture-by-value is correct and the asynchronously
</span>    <span class="comment single">// dispatched closure may outlive the originating class,
</span>    <span class="comment single">// and may be freely copied without losing correctness.
</span>    <span class="punctuation">{</span> <span class="keyword">return</span> <span class="name">std</span><span class="operator">::</span><span class="name">async</span><span class="punctuation">(</span> <span class="punctuation">[</span><span class="operator">*</span><span class="punctuation">]()</span><span class="operator">-&gt;</span><span class="keyword type">int</span><span class="punctuation">{</span> <span class="keyword">return</span> <span class="name">value</span> <span class="punctuation">;</span> <span class="punctuation">});</span> <span class="punctuation">}</span>

  <span class="comment single">// Trivial change to replace 'for' with 'parallel for'
</span>  <span class="keyword type">void</span> <span class="name">do_something</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="punctuation">{</span>
    <span class="comment single">// for ( int i = 0 ; i &lt; N ; ++i )
</span>    <span class="name">foreach</span><span class="punctuation">(</span> <span class="name">Parallel</span> <span class="punctuation">,</span> <span class="literal number integer">0</span> <span class="punctuation">,</span> <span class="name">N</span> <span class="punctuation">,</span> <span class="punctuation">[</span><span class="operator">*</span><span class="punctuation">](</span> <span class="keyword type">int</span> <span class="name">i</span> <span class="punctuation">)</span>
    <span class="punctuation">{</span>
      <span class="comment single">// A modestly long loop body where
</span>      <span class="comment single">// every reference to a member can be
</span>      <span class="comment single">// safely referenced without modification.
</span>    <span class="punctuation">}</span>
    <span class="punctuation">);</span>
  <span class="punctuation">}</span>
<span class="punctuation">};</span>
</pre>
<!--  -->
</div>
</div>
</div>
</body>
</html>
