title: How to have template type deduced in std::function arguments with lambda?
body: <p>I have a boost::variant and I would like to execute a functor only if the variant is of a special type, so I made up this function: </p>
  
  <pre><code>template&lt;typename T, typename Variant&gt;
  void if_init(Variant&amp; opt_variant, std::function&lt;void(T)&gt; functor){
      if(auto* ptr = boost::get&lt;T&gt;(&amp;opt_variant)){
          functor(*ptr);
      }   
  }
  </code></pre>
  
  <p>This works well, but I would like the type T to be deduced, so that I can write that:</p>
  
  <pre><code>if_init(b, [](double var){ std::cout &lt;&lt; "I'm double and set" &lt;&lt; std::endl; });
  </code></pre>
  
  <p>But the type is not deduced: </p>
  
  <pre><code>type_inference.cpp:19:5: error: no matching function for call to 'if_init'
      if_init(b, [](double var){ std::cout &lt;&lt; "I'm double and set" &lt;&lt; std::endl; }); 
      ^~~~~~~
  type_inference.cpp:10:6: note: candidate template ignored: failed template argument deduction
      void if_init(Variant&amp; opt_variant, std::function&lt;void(T)&gt; functor){
  </code></pre>
  
  <p>If I write:</p>
  
  <pre><code>if_init&lt;double&gt;(b, [](double var){ std::cout &lt;&lt; "I'm double and set" &lt;&lt; std::endl; });
  </code></pre>
  
  <p>it works well. </p>
  
  <p>Is there a way to have type T being deduced ? I would like to type T only once. Here the type is short, but in the real case, there are long types. </p>
  
  <p>I'm using CLang 3.2. </p>
  
  <p>Here is the full test case (the first call compiles not the second):</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;functional&gt;
  #include &lt;boost/variant.hpp&gt;
  
  typedef boost::variant&lt;int, double&gt; Test;
  
  template&lt;typename T, typename Variant&gt;
  void if_init(Variant&amp; opt_variant, std::function&lt;void(T)&gt; functor){
      if(auto* ptr = boost::get&lt;T&gt;(&amp;opt_variant)){
          functor(*ptr);
      }   
  }
  
  int main(){
      Test b = 1.44; 
  
      if_init&lt;double&gt;(b, [](double var){ std::cout &lt;&lt; "I'm double and set" &lt;&lt; std::endl; });
      if_init(b, [](int var){ std::cout &lt;&lt; "I'm int and set" &lt;&lt; std::endl; });      
  
      return 0;
  }
  </code></pre>