title: Generically wrap member function of object to modify return type
body: <p>Version restriction: C++17.</p>
  <p>I'm trying to create a type capable of accepting a callable object of any type and wrapping one of its member functions (in this case, <code>operator()</code>) to take the same arguments, but modify (cast) the return type. An example follows:</p>
  <pre><code>template &lt;typename Ret, typename Callable&gt;
  struct ReturnConverter : Callable
  {
      ReturnConverter(Callable cb) : Callable(cb) { }
  
      Ret operator()(argsof(Callable::operator()) args)  // magic happens here
      {
          return static_cast&lt;Ret&gt;(Callable::operator()(std::forward&lt;??&gt;(args)); // how to forward?
      }
  };
  
  template &lt;typename Ret, typename Callable&gt;
  auto make_converter(Callable cb)
  {
      return ReturnConverter&lt;Ret, Callable&gt;(cb);
  }
  
  int main()
  {
      auto callable = []() { return 1.0f; };
      auto converted = make_converter&lt;int&gt;(callable);
  
      auto x = converted(); // decltype(x) = int
  }
  </code></pre>
  <p><code>ReturnConverter</code> can take an object and override that object's <code>operator()</code> to cast whatever it returns to <code>Ret</code>.</p>
  <p>The problem is expressing the argument types of the wrapping function - they should be exactly the same as those of <code>Callable::operator()</code>. Using a variadic template with <code>std::forward</code> does not satisfy this goal, as it would modify the signature of the function (<code>operator()</code> now becomes a template where it wasn't before).</p>
  <p>How can I express the <strong><code>argsof</code></strong> operator I've highlighted above?</p>
  <hr>
  <p><em>Motivation</em>: I'd like to modify the <code>std::visit</code> overload technique demonstrated in <a href="https://www.cppstories.com/2018/09/visit-variants/" rel="nofollow noreferrer">this article</a> to be able to specify the desired return type from multiple lambda functors, so that I don't have to strictly match the return type in every lambda, for instance:</p>
  <pre><code>std::variant&lt;int, float, void*&gt; v = ...;
  auto stringify = overload(
      [](int x) { return &quot;int: &quot; + std::to_string(x); },
      [](float x) { return &quot;float: &quot; + std::to_string(x); },
      [](auto v) { return &quot;invalid type!&quot;; }  // error! const char* != std::string
  );
  std::visit(stringify, v);
  </code></pre>
  <p>With the change above, I'd be able to write something like <code>auto stringify = overload&lt;std::string&gt;(...);</code></p>