title: Arbitrary type transformations of functor arguments and results
body: <p>I have a class something like this:</p>
  
  <pre><code>template &lt;typename T&gt;
  struct operation {
      typedef T result_type;
      typedef ::std::shared_ptr&lt;operation&lt;T&gt; &gt; ptr_t;
  };
  </code></pre>
  
  <p>I have a functor that would match this <code>::std::function</code> type:</p>
  
  <pre><code>::std::function&lt;int(double, ::std::string)&gt;
  </code></pre>
  
  <p>I want to create a functor that has a signature something like this:</p>
  
  <pre><code>operation&lt;int&gt;::ptr_t a_func(operation&lt;double&gt;::ptr_t, operation&lt; ::std::string&gt;::ptr_t);
  </code></pre>
  
  <p>I want to do this in an automated fashion so I can create a similar functor for any given <code>::std::function</code> type.</p>
  
  <p>Lastly, I would like to put this wrinkle in. This:</p>
  
  <pre><code>::std::function&lt;int(operation&lt;double&gt;::ptr_t, ::std::string)&gt;
  </code></pre>
  
  <p>should result in this:</p>
  
  <pre><code>operation&lt;int&gt;::ptr_t a_func(operation&lt;double&gt;::ptr_t, operation&lt; ::std::string&gt;::ptr_t);
  </code></pre>
  
  <p>Because if a functor already accepts an <code>operation&lt;T&gt;::ptr_t</code> that means it understands what they are and is willing to deal with their asynchronous nature itself.</p>
  
  <p>How would I do this? I have a naive and partially working attempt here:</p>
  
  <pre><code>template &lt;typename argtype&gt;
  struct transform_type {
     typedef typename operation&lt;argtype&gt;::ptr_t type;
  };
  
  template &lt;typename ResultType, typename... ArgTypes&gt;
  ::std::function&lt;typename transform_type&lt;ResultType&gt;::type(typename transform_type&lt;ArgTypes...&gt;::type)&gt;
  make_function(::std::function&lt;ResultType(ArgTypes...)&gt;)
  {
     return nullptr;
  }
  </code></pre>
  
  <p>It doesn't detect arguments that are already of type <code>std::shared_ptr&lt;operation&lt;T&gt; &gt;</code> though. And this specialization of transform_type fails to compile:</p>
  
  <pre><code>template &lt;typename argtype&gt;
  struct transform_type&lt;typename operation&lt;argtype&gt;::ptr_t&gt;
  {
     typedef typename stub_op&lt;argtype&gt;::ptr_t type;
  };
  </code></pre>