title: std::function as a (non) const input parameter sent by &
body: <p>I wonder why <code>std::function&lt;...(...)&gt; &amp;</code> needs to be specified as <code>const</code> when passed as an input parameter to a function. AFAIK there is no way to change it, right? Here is an example that compiles and runs fine. If I remove the <code>const</code> qualifier I get an error:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;functional&gt;
  
  //int foo(std::function&lt;int(int)&gt; &amp;f)
  int foo(const std::function&lt;int(int)&gt; &amp;f)
  {
      return f(6);
  }
  int main(int argc, char **argv)
  {
      auto f1 = [=](int i){ if (i&lt;5) {return 8*2;} else {return 2;} };
      auto f2 = [=](int i){ if (i&gt;3) {return i*i;} else {return 2;} };
      std::cout &lt;&lt; foo(f1) &lt;&lt; "\n";
  }
  </code></pre>
  
  <p>When I use the declaration without the <code>const</code> I get the following error:</p>
  
  <pre><code>main.cpp: In function ‘int main(int, char**)’:
  main.cpp:13:21: error: cannot bind non-const lvalue reference of type ‘std::function&lt;int(int)&gt;&amp;’ to an rvalue of type ‘std::function&lt;int(int)&gt;’
    std::cout &lt;&lt; foo(f1) &lt;&lt; "\n";
                       ^
  In file included from /usr/include/c++/7/functional:58:0,
                   from main.cpp:2:
  /usr/include/c++/7/bits/std_function.h:685:7: note:   after user-defined conversion: std::function&lt;_Res(_ArgTypes ...)&gt;::function(_Functor) [with _Functor = main(int, char**)::&lt;lambda(int)&gt;; &lt;template-parameter-2-2&gt; = void; &lt;template-parameter-2-3&gt; = void; _Res = int; _ArgTypes = {int}]
         function&lt;_Res(_ArgTypes...)&gt;::
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
  main.cpp:4:5: note:   initializing argument 1 of ‘int foo(std::function&lt;int(int)&gt;&amp;)’
   int foo(std::function&lt;int(int)&gt; &amp;f)
       ^~~
  </code></pre>