Catching and wrapping exceptions with boost::optional
<p>I'd like to catch exceptions generated by library code and wrap them in <code>boost::optional</code>s (or <code>std::experimental::optional</code>). My code works for the trivial cases, but has difficulty deducing the correct type when calling overloaded functions. I've reduced my test case to this:</p>

<pre class="lang-cpp prettyprint-override"><code>// Compile with: clang++ -std=c++14 -stdlib=libc++ -Wall -Wshadow -Wextra -o except_to_optional except_to_optional.cpp
#include &lt;iostream&gt;
#include &lt;boost/optional.hpp&gt;

template&lt;typename Func, typename... Args&gt;
auto try_call(Func f, Args&amp;&amp;... args) noexcept -&gt; boost::optional&lt;std::decay_t&lt;decltype(f(std::forward&lt;Args&gt;(args)...))&gt;&gt;
{
  using RT = std::decay_t&lt;decltype(f(std::forward&lt;Args&gt;(args)...))&gt;;
  try {
    return boost::make_optional&lt;RT&gt;(f(std::forward&lt;Args&gt;(args)...));
  } catch(...) {
    return boost::none;
  }
}

int func1(char * ptr)
{
  if (!ptr)
    throw 14;

  return strlen(ptr);
}

int func1(char * ptr, size_t len)
{
  if (!ptr)
    throw 14;

  const size_t calc_len = strlen(ptr);
  return calc_len &lt; len ? calc_len : len;
}

int main(int argc, char **argv)
{
  char *omg = "omg";

#if 1
  // This is the desired syntax, but it fails
  auto val = try_call(func1, omg);
#else
  // This works, but its ugly
  int (*f)(char *) = func1;
  auto val = try_call(f, omg);
#endif

  if (val)
    std::cout &lt;&lt; omg &lt;&lt; " has a length of " &lt;&lt; *val &lt;&lt; "\n";
  else
    std::cout &lt;&lt; "Something went wrong...\n";

  return 0;
}
</code></pre>

<p>When attempting to compile the "broken" example, I get the following output:</p>

<pre class="lang-none prettyprint-override"><code>except_to_optional.cpp:50:14: error: no matching function for call to 'try_call'
  auto val = try_call(func1, omg);
             ^~~~~~~~
except_to_optional.cpp:17:6: note: candidate template ignored: couldn't infer template argument 'Func'
auto try_call(Func f, Args&amp;&amp;... args) noexcept -&gt; boost::optional&lt;std::decay_t&lt;decltype(f(std::forward&lt;Args&gt;(args)...))&gt;&gt;
     ^
</code></pre>

<p>I'm able to side-step the issue by creating a function pointer with the correct type, but this isn't ideal. Is there a solution to my problem or am I stuck with the ugly function pointer hack?</p>

<p>Cheers,
Ryan</p>