<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<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>A type trait for signatures</title>
<body>
<p>N3579<br/>
Revision of N3466=12-0156<br/>
    2013-03-15<br/>
    Mike Spertus<br/>
    <a href="mailto:mike_spertus@symantec.com"><tt>mike_spertus@symantec.com</tt></a><br/></p>

<h1>A type trait for signatures</h1>
<h2>Overview</h2>
<p>We propose 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 
<code>struct C {
  int operator()(double d, int i);
  int operator()(double d1, double d2);
};
</code>
then <tt>std::signature&lt;C(int, int)&gt;::type</tt> would be <tt>int(double, double)</tt>.
More precisely the return type of <tt>signature&lt;Fn(ArgTypes...)&gt;</tt> is 
<tt>result_of&lt;Fn(ArgTypes...)&gt;</tt> and each argument type is the same
as the formal parameter type matched in the call to <tt>Fn</tt>. For more detailed
information, see the <a href="#uc">use cases</a> and <a href="#wording">wording</a> below.</p>		
<a name="uc"></a><h2>Example application: More perfect forwarding</h2>
<p>This section gives several examples of using <tt>std::signature</tt> to
create transparent forwarding functions. Note that this paper does not propose
changing <tt>async</tt>, etc., but to illustrate, as Pablo Halpern has said,
that the problem is real for any "pass-through" functions that need to capture
arguments.</p>

<p>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 &amp;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">// Ill-formed: i not passed by reference</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. 

While the above example is at least a compile error, we can even get
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>While this paper is definitely not proposing a change to <tt>std::async</tt>,
 we can illustrate how the <tt>signature</tt> trait could be used to create a
   "More Perfect Forwarding async"
    that 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>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 &amp;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>

<p>Pablo Halpern mentions in N3557 that that a theoretical library implementation of fork-join parallelism would benefit
from a <tt>signature</tt> type trait for similar reasons, resulting in 
fewer programmer errors in asynchronous parameter passing.</p>
<p>Finally, a more perfectly forwarding function binder could also be useful for some applications
for more precisely calling the bound function</p>
<a name="wording"></a><h2>Wording</h2>
Change the end of &sect;20.9.2 [meta.type.synop] to 
<blockquote>
<pre style="padding:0;margin:0">  template &lt;class&gt; class result_of; <span class="comment">// not defined</span>
  template &lt;class F, class... ArgTypes&gt; class result_of&lt;F(ArgTypes...)&gt;;
<span class="ins">  template &lt;class&gt; class signature; <span class="comment">// not defined</span></span>
<span class="ins">  template &lt;class F, class... ArgTypes&gt; class signature&lt;F(ArgTypes...)&gt;;</span>
} <span class="comment">// namespace std</span></pre></blockquote>
Add the following row to the end of table 57 in @sect;20.9.7.6 [meta.trans.other]
<blockquote><table bgcolor="#A0FFA0" summary="">
<tr><td><tt>template &lt;class Fn,
class... ArgTypes&gt; struct
signature&lt;Fn(ArgTypes...)&gt;;</tt></td><td>Fn shall be a callable
type (20.8.1), reference to
function, or reference to
callable type. The
expression
<tt>INVOKE(declval&lt;Fn&gt;(),
declval&lt;ArgTypes&gt;()...)</tt>
shall be well formed.</td>
<td>The member typedef <tt>type</tt> shall name the type 
<tt>result_of&lt;Fn(ArgTypes...)&gt;::type(T1, T2, ..., Tn)</tt>
where each <tt>Ti</tt> is the type of the formal
parameter of the <em>callable type</em> (20.8.1) matched by the ith
object of <tt>declval&lt;ArgTypes&gt;()...</tt> in the above
<tt>INVOKE</tt> expression. If <tt>Fn</tt> is a pointer to member
type, <tt>T1</tt> will be either a pointer or reference to the
containing class (with the same cv-qualification as <tt>Fn</tt>) according to
whether the first element of <tt>ArgTypes...</tt> is a pointer or reference
type.</td></tr>
</table></blockquote>
</body></html>
