<?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>P0018r1 : 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-10-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="p0018r1-lambda-capture-of-this-by-value">
<h1 class="title">P0018r1 : 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>1</td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2015-10-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 the <strong>this</strong> pointer to access to member variables
of <strong>this</strong>.
Both capture-by-reference <strong>[&amp;]</strong> and capture-by-value <strong>[=]</strong>
<em>capture-defaults</em> 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 the <strong>*this</strong> object by value allows an implicitly declared
closure to be copied before invoking the closure's function.</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 is 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 <strong>*this</strong> object <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 significantly
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 a true (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> <em>member</em> instead of a <strong>tmp.</strong> <em>member</em>
as there are two distinct objects in the closure that
reference two distinct <em>member</em> of the same name.
Second, it is onerous and counter-productive
to the introduction of asynchronously dispatched lambda expressions
within existing code.
Consider 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 includes a member instance of the type of <strong>*this</strong>,</li>
<li>the enclosing function's <strong>*this</strong> is copy constructed into the corresponding member of the closure,</li>
<li>name lookup (5.1.2p7) of <strong>this</strong>, <strong>*this</strong>, and non-static members of <strong>*this</strong> translate to the closure's copy of <strong>*this</strong>, and</li>
<li>if the lambda is not mutable then the closure's copy of <strong>*this</strong> is <strong>const</strong>.</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
cannot occur within a copy constructor
or function invoked by a copy constructor.
Such a circumstance would result in an
infinite recursion of the copy constructor.
Note that his requirement is also applicable to the onerous work-around
of <strong>[tmp=*this]</strong>.</p>
</div>
<div class="section" id="impractical-preferred-solution-correct-lambda-capture-by-value">
<h1>4&nbsp;&nbsp;&nbsp;Impractical Preferred Solution: Correct Lambda Capture-by-value <strong>[=]</strong></h1>
<p>The semantically consistent solution 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 solution corrects lambda capture semantics;
however, it is likely to break existing code
conforming to the C++11 standard which depend
on the copying of the <strong>this</strong> pointer rather
than copying of the object to which the <strong>this</strong> pointer refers.
As such we currently consider this solution to be impractical
and propose the following pragmatic solution.</p>
</div>
<div class="section" id="pragmatic-solution-add-lambda-capture-this-by-value-this">
<h1>5&nbsp;&nbsp;&nbsp;Pragmatic Solution: Add Lambda Capture-*this-by-value <strong>[=,*this]</strong></h1>
<p>Given that the semantically consistent preferred solution 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>
<div class="section" id="draft-wording">
<h2>5.1&nbsp;&nbsp;&nbsp;Draft wording</h2>
<p>Feature test macro:  <strong>__cpp_lambda_capture_this_object_by_value</strong></p>
<dl class="docutils">
<dt><strong>5.1.2p1:</strong> Extend the <em>simple-capture</em> to include <strong>*this</strong>.</dt>
<dd><div class="first last line-block">
<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>
</dd>
<dt><strong>5.1.2p8:</strong> Revise for capture of <strong>*this</strong> by value.</dt>
<dd>If a <em>lambda-capture</em> includes a <em>capture-default</em> that is <strong>=</strong> then
the <em>lambda-capture</em> shall not contain <strong>this</strong>,
the <em>lambda-capture</em> may contain <strong>*this</strong> to capture <strong>*this</strong> by value,
and each remaining identifier the <em>lambda-capture</em> contains shall be
preceeded by <strong>&amp;</strong>.
An identifier, <strong>this</strong>, or <strong>*this</strong> shall not appear more than
once in a <em>lambda-capture</em>.
Both <strong>this</strong> and <strong>*this</strong> shall not appear in the same <em>lambda-capture</em>.
When <strong>*this</strong> object is captured by value the <strong>this</strong> pointer shall
not be captured.</dd>
<dt><strong>5.1.2 new paragraph</strong></dt>
<dd>Explicit <em>lambda-capture</em> of <strong>*this</strong> requires that
the type of <strong>*this</strong> is copy constructable.
A <em>lambda-capture</em> of <strong>*this</strong> within the context of the
copy constructor for the type of <strong>*this</strong> implicitly
requires infinite recursion of that copy constructor
and is thus ill-formed.</dd>
<dt><strong>5.1.2p10:</strong> Modify for capture of <strong>*this</strong> by value.</dt>
<dd>An entity (i.e., a variable, <strong>this</strong>, or <strong>*this</strong>) is said
to be ...</dd>
<dt><strong>5.1.2p12:</strong> Modify to add <strong>*this</strong></dt>
<dd>If a <em>lambda-expression</em> odr-uses (3.2) <strong>this</strong>, <strong>*this</strong>,
or a variable with ...</dd>
<dt><strong>5.1.12p15:</strong> insert</dt>
<dd>The <strong>*this</strong> entity is <em>captured by copy</em> if it is
explicitly captured.</dd>
<dt><strong>5.1.12p17:</strong> insert</dt>
<dd>If <strong>*this</strong> is captured, each odr-use of <strong>*this</strong> is
transformed into an access to the corresponding unnamed
data member of the closure type which is of the type of <strong>*this</strong>.
[Note: Thus an odr-use of <strong>*this</strong> in a nested <em>lambda-expression</em>
is likewise transformed. --end note]</dd>
</dl>
</div>
<div class="section" id="example-for-nested-lambda-expressions">
<h2>5.2&nbsp;&nbsp;&nbsp;Example for nested lambda expressions</h2>
<p>A new capture mechanism introduces a new capture interaction.
For non-<strong>*this</strong> captures the interactions remain unchanged.
When <strong>*this</strong> is captured by value via <strong>[*this]</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="operator">*</span><span class="keyword">this</span><span class="punctuation">]()</span> <span class="punctuation">{</span>
    <span class="comment single">// this, *this, and member variables of Work refer to
</span>    <span class="comment single">// the copy *this contained in closure 'x'
</span>    <span class="comment single">// does not refer to the original enclosing 'this'
</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">// this, *this, and member variables of Work refer to
</span>      <span class="comment single">// the copy *this contained in closure 'x'
</span>      <span class="comment single">// does not refer to the original enclosing 'this'
</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">// this, *this, and member variables of Work refer to
</span>      <span class="comment single">// the copy *this contained in closure 'x'
</span>      <span class="comment single">// does not refer to the original enclosing 'this'
</span>    <span class="punctuation">};</span>
    <span class="keyword">auto</span> <span class="name">zz</span> <span class="operator">=</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">,</span><span class="operator">*</span><span class="keyword">this</span><span class="punctuation">]()</span> <span class="punctuation">{</span>
      <span class="comment single">// this, *this, and member variables of Work refer to
</span>      <span class="comment single">// a new copy *this contained in closure 'z'
</span>      <span class="comment single">// that is copied from the copy of *this contained
</span>      <span class="comment single">// in the closure 'x'
</span>    <span class="punctuation">};</span>
  <span class="punctuation">};</span>
<span class="punctuation">}</span>
</pre>
<!--  -->
</div>
<div class="section" id="updated-example">
<h2>5.3&nbsp;&nbsp;&nbsp;Updated example</h2>
<p>With proper lambda capture-by-value the earlier examples
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="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="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">do_something</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="punctuation">{</span>
    <span class="comment single">// Trivial change to replace 'for' with asynchronously
</span>    <span class="comment single">// dispatched parallel foreach.
</span>    <span class="comment single">// for ( int i = 0 ; i &lt; N ; ++i )
</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">todo</span> <span class="operator">=</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="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 non-trivial loop body where
</span>        <span class="comment single">// every reference to a member is
</span>        <span class="comment single">// safely accessed from the
</span>        <span class="comment single">// captured-by-value *this
</span>      <span class="punctuation">});</span>
    <span class="keyword">return</span> <span class="name">todo</span> <span class="punctuation">;</span>
  <span class="punctuation">}</span>
<span class="punctuation">};</span>
</pre>
<!--  -->
</div>
</div>
<div class="section" id="follow-up-capture-default">
<h1>6&nbsp;&nbsp;&nbsp;Follow-up: capture-default <strong>[=*]</strong></h1>
<p>Assuming that correcting the <em>capture-default</em> behavior of <strong>[=]</strong>
is impractical we seek a <em>capture-default</em> expression
to simplify the true capture-by-value expression <strong>[=,*this]</strong>.
A possible <em>capture-default</em> expression is to let <strong>[=*]</strong> be
equivalent to <strong>[=]</strong> outside of a non-static member function
and equivalent to <strong>[=,*this]</strong> within a non-static member function.</p>
</div>
</div>
</body>
</html>
