﻿<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body>﻿


<style type="text/css">
.comment { color: #999999; font-style: italic; }
.pre { color: #000099; }
.string { color: #009900; }
.char { color: #009900; }
.float { color: #996600; }
.int { color: #999900; }
.bool { color: #000000; font-weight: bold; }
.type { color: #FF6633; }
.flow { color: #FF0000; }
.keyword { color: #990000; }
.operator { color: #663300; font-weight: bold; }
.operator { color: #663300; font-weight: bold; }
pre.code {
    border: 2px solid #666;
    background-color: #F4F4F4;
    padding-left: 10px;
    padding-top: 0px;
}
code {
    border: 2px solid #d0d0d0;
    background-color: LightYellow;
    padding: 2px;
    padding-left: 10px;
    display:table;
    white-space:pre;
    margin:2px;
    margin-bottom:10px;
}
dt
{
    font-weight: bold;
}
    
.ins {
    background-color:#A0FFA0;
}

.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}    
</style>    <title>More Perfect Forwarding</title>
<body>

N3466=12-0156<br>
    2012-11-03<br>
    Mike Spertus<br>
    <a href="mailto:mike_spertus@symantec.com"><tt>mike_spertus@symantec.com</tt></a><br>

    <h1>More Perfect Forwarding</h1>
    <h2>The problem</h2>
The moment a programmer first encounters multithreaded programs, they run into 
    surprises like the following example:
<code>// Inspired by examples in section 2.2 of Anthony Williams <em>C++ Concurrency in Action</em>
void f(int &i) { i = 2; <span class="comment">/* ... */</span> }
int i;
f(i); <span class="comment">// i passed by reference, f can change i</span>
thread tf = thread(f, i); <span class="comment">// i not passed by reference, so changes to i are silently discarded</span>
</code>
While they can always force a pass by reference,e.g., by
<code>thread t(f, ref(i));</code>
this is entirely different from how functions arguments are ordinarily passed, and omitting the
    <tt>ref</tt> is likely to result in a silent failure.

We can even have silent errors introduced for parameters that are passed by value
<code>// Another variation on an example in section 2.2 of Anthony Williams <em>C++ Concurrency in Action</em>
void f(int i,std::string s); // Unlike in the book, s is passed by value.
void my_oops(int some_param)
{
  char buffer[1024];
  sprintf(buffer, "%i",some_param);
  <span class="comment">// Intermittent failures as buffer may not be converted to a string during the lifetime of buffer</span>
  std::thread t(f,3,buffer);  
  t.detach();
}
</code>
<p>I believe requiring most C++ programmers to be conversant with these kinds of silent change of signature
    is a pretty high bar.
    This is borne out by my experience teaching C++ to Masters' students, possibly because
    the reason for this change isn't apparent until one is comfortable writing templates,
    instead they naturally expect asynchronous functions to obey the same parameter
    passing rules as ordinary functions.
</p>
    <p><b>Note:  </b>All of the above discussion applies equally to <tt>bind</tt>.</p>
<h2>Proposed solution</h2>
<p>The underlying problem for this and similar problems is that we cannot deduce the 
    function signature of a callable template. <tt>std::result_of</tt> can give us the
    return type but not the parameter types.</p>
<p>We propose addressing this with a (compiler-supported) type trait <tt>std::signature</tt> whose <tt>type</tt> typedef is the function
type of the callable object when called with the given parameter types.</p>
<p>For example, if we define <tt>C</tt> as </p>
<code>struct C {
  int operator()(double d, int i);
  int operator()(double d1, double d2);
};
</code>
then <tt>signature&lt;C(int, int)&gt;::type</tt> would be <tt>int(double, double)</tt>.

<p>As an extended example, we can create a new async that avoids the above problems
    by taking its arguments with the same signature as its callable does:
    
</p>
<code><span class="comment">// more_perfect_forwarding_async.h</span>
#include&lt;iostream&gt;
#include&lt;utility&gt;
#include&lt;future&gt;
#include&lt;type_traits&gt;
<span class="comment">// Uses "apply" template for unpacking tuple members into arguments written by DRayX at</span>
<span class="comment">// http://stackoverflow.com/questions/687490/how-do-i-expand-a-tuple-into-variadic-template-functions-arguments</span>
#include&quot;apply.h&quot; 

template&lt;typename Callable, typename Signature&gt; struct Caller;
template&lt;typename Callable, typename Result, typename...Args&gt;
struct Caller&lt;Callable, Result(Args...)&gt; {
  Caller(Callable c, Args&amp;&amp;... args) : callable(c), saved_args(std::forward&lt;Args...&gt;(args...)) {}
  Result operator()() { return apply(callable, saved_args); }
  std::tuple&lt;Args...&gt; saved_args;
  Callable callable;
};

template&lt;typename Callable, typename... Args&gt;
future&lt;typename result_of&lt;Callable(Args...)&gt;::type&gt;
more_perfect_forwarding_async(Callable c, Args&amp;&amp;... args)
{
  return std::async(Caller&lt;Callable, typename signature&lt;Callable(Args...)&gt;::type&gt;(c, std::forward&lt;Args&gt;(args)...));
}
</code>
<div style="padding-left: 3em;text-indent: -3em"><b>Note: </b>This uses complicated template metafunction
    given by
    DRayX on <a href="http://stackoverflow.com/questions/687490/how-do-i-expand-a-tuple-into-variadic-template-functions-arguments">StackOverflow</a> to unpack tuple members into a function argument list .
    See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3416.html">N3416: Packaging Parameter Packs</a> for an alternative approach not requiring metaprogramming.</div>
</p>
<p>Now, we can run asynchronous functions without worrying about implicit signature changes</p>
<code>#include"more_perfect_forwarding_async.h"
#include&lt;iostream&gt;
int func(int &i) { i = 2; return i; }

int main()
{
  int i = 5;
  auto f = more_perfect_forwarding_async(func, i);
  f.get();
  cout << "i = " << i << endl; <span class="comment">// Correctly prints 2 </span>
}
</code>
<h3>Implementation status</h3>
I validated the code for <tt>more_perfect_forwarding_async</tt> on g++ 4.7.2 with an explicit specialization for <tt>signature</tt>. A compiler-supported <tt>signature</tt> 
    type trait is expected for Bristol.
</body></html>
