title: Is it possible to static_assert that a lambda is not generic?
body: <p>I implemented a Visit function (on a variant) that checks that the currently active type in the variant matches the function signature (more precisely the first argument). Based on this nice <a href="https://stackoverflow.com/a/35348334/700825">answer</a>.
  For example</p>
  
  <pre><code>#include &lt;variant&gt;
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  
  template&lt;typename Ret, typename Arg, typename... Rest&gt;
  Arg first_argument_helper(Ret(*) (Arg, Rest...));
  
  template&lt;typename Ret, typename F, typename Arg, typename... Rest&gt;
  Arg first_argument_helper(Ret(F::*) (Arg, Rest...));
  
  template&lt;typename Ret, typename F, typename Arg, typename... Rest&gt;
  Arg first_argument_helper(Ret(F::*) (Arg, Rest...) const);
  
  template &lt;typename F&gt;
  decltype(first_argument_helper(&amp;F::operator())) first_argument_helper(F);
  
  template &lt;typename T&gt;
  using first_argument = decltype(first_argument_helper(std::declval&lt;T&gt;()));
  
  std::variant&lt;int, std::string&gt; data="abc";
  template &lt;typename V&gt;
  void Visit(V v){
  using Arg1 = typename std::remove_const_t&lt;std::remove_reference_t&lt;first_argument&lt;V&gt;&gt;&gt;;//... TMP magic to get 1st argument of visitor + remove cvr, see Q 43526647
  if (! std::holds_alternative&lt;Arg1&gt;(data)) {
  std::cerr&lt;&lt; "alternative mismatch\n";
  return;
  }
  v(std::get&lt;Arg1&gt;(data));
  }
  int main(){
      Visit([](const int&amp; i){std::cout &lt;&lt; i &lt;&lt; "\n"; });
      Visit([](const std::string&amp; s){std::cout &lt;&lt; s &lt;&lt; "\n"; });
      // Visit([](auto&amp; x){}); ugly kabooom
  }
  </code></pre>
  
  <p>This works, but it explodes with a user unfriendly compile time error when users passes a generic (e.g. <code>[](auto&amp;){}</code>) lambda. Is there a way to detect this and give nice <code>static_assert()</code> about it?
  Would also be nice if it worked with function templates as well, not just with lambdas.</p>
  
  <p>Note that I do not know what possible lambdas do, so I can not do some clever stuff with Dummy types since lambdas may invoke arbitrary functions on types.
  In other words I can not try to call lambda in 2 <code>std::void_t</code> tests on <code>int</code> and <code>std::string</code> and if it works assume it is generic because they might try to call <code>.BlaLol()</code> on <code>int</code> and <code>string</code>.</p>