title: How to deduce the return type of a function object from parameters list?
body: <p>I'm trying to write a projection function that could transform a <code>vector&lt;T&gt;</code> into a <code>vector&lt;R&gt;</code>. Here is an example:</p>
  
  <pre><code>auto v = std::vector&lt;int&gt; {1, 2, 3, 4};
  auto r1 = select(v, [](int e){return e*e; }); // {1, 4, 9, 16}
  auto r2 = select(v, [](int e){return std::to_string(e); }); // {"1", "2", "3", "4"}
  </code></pre>
  
  <p>First attempt:</p>
  
  <pre><code>template&lt;typename T, typename R&gt;
  std::vector&lt;R&gt; select(std::vector&lt;T&gt; const &amp; c, std::function&lt;R(T)&gt; s)
  {
     std::vector&lt;R&gt; v;
     std::transform(std::begin(c), std::end(c), std::back_inserter(v), s);
     return v;
  }
  </code></pre>
  
  <p>But for </p>
  
  <pre><code>auto r1 = select(v, [](int e){return e*e; });
  </code></pre>
  
  <p>I get:</p>
  
  <blockquote>
    <p>error C2660: 'select' : function does not take 2 arguments</p>
  </blockquote>
  
  <p>I have to explicitly call <code>select&lt;int,int&gt;</code> to work. I don't like this because the types are redundant.</p>
  
  <pre><code>auto r1 = select&lt;int, int&gt;(v, [](int e){return e*e; }); // OK
  </code></pre>
  
  <p>Second attempt:</p>
  
  <pre><code>template&lt;typename T, typename R, typename Selector&gt;
  std::vector&lt;R&gt; select(std::vector&lt;T&gt; const &amp; c, Selector s)
  {
     std::vector&lt;R&gt; v;
     std::transform(std::begin(c), std::end(c), std::back_inserter(v), s);
     return v;
  }
  </code></pre>
  
  <p>The result is same error, function does not take 2 arguments. In this case I actually have to supply a 3rd type argument:</p>
  
  <pre><code>auto r1 = select&lt;int, int, std::function&lt;int(int)&gt;&gt;(v, [](int e){return e*e; });
  </code></pre>
  
  <p>Third attempt: </p>
  
  <pre><code>template&lt;typename T, typename R, template&lt;typename, typename&gt; class Selector&gt;
  std::vector&lt;R&gt; select(std::vector&lt;T&gt; const &amp; c, Selector&lt;T,R&gt; s)
  {
     std::vector&lt;R&gt; v;
     std::transform(std::begin(c), std::end(c), std::back_inserter(v), s);
     return v;
  }
  </code></pre>
  
  <p>For </p>
  
  <pre><code>auto r1 = select&lt;int, int, std::function&lt;int(int)&gt;&gt;(v, [](int e){return e*e; });
  </code></pre>
  
  <p>the error is:</p>
  
  <blockquote>
    <p>'select' : invalid template argument for 'Selector', class template expected</p>
  </blockquote>
  
  <p>For </p>
  
  <pre><code>auto r1 = select(v, [](int e){return e*e; });
  </code></pre>
  
  <blockquote>
    <p>error C2660: 'select' : function does not take 2 arguments</p>
  </blockquote>
  
  <p>(I know the last two attempts are not particularly great.)</p>
  
  <p>How can I write this <code>select()</code> template function to work for the sample code I put in the beginning?</p>