title: get const or non-const reference type from trait
body: <p>I am writing a functor F which takes function of type void (*func)(T) and func's argument arg.</p>
  
  <pre><code>template&lt;typename T&gt;
    void F(void (*func)(T), WhatTypeHere? arg)
  {
    func(arg);
  }
  </code></pre>
  
  <p>Then functor F calls func with arg. I would like F not to copy arg, just to pass it as reference. But then I cannot simply write "void F(void (*func)(T), T&amp;)" because T could be a reference. So I am trying to write a trait, which allows to get proper reference type of T:</p>
  
  <pre><code>T -&gt; T&amp;
  T&amp; -&gt; T&amp;
  const T -&gt; const T&amp;
  const T&amp; -&gt; const T&amp;
  </code></pre>
  
  <p>I come up with something like this:</p>
  
  <pre><code>template&lt;typename T&gt;
   struct type_op
  {
   typedef T&amp; valid_ref_type;
  };
  
  template&lt;typename T&gt;
   struct type_op&lt;T&amp;&gt;
  {
   typedef typename type_op&lt;T&gt;::valid_ref_type valid_ref_type;
  };
  
  template&lt;typename T&gt;
   struct type_op&lt;const T&gt;
  {
   typedef const T&amp; valid_ref_type;
  };
  
  template&lt;typename T&gt;
   struct type_op&lt;const T&amp;&gt;
  {
   typedef const T&amp; valid_ref_type;
  };
  
  
  template&lt;typename T&gt;
    void F(void (*func)(T), typename type_op&lt;T&gt;::valid_ref_type arg)
  {
    func(arg);
  }
  </code></pre>
  
  <p>Which doesn't work for example for</p>
  
  <pre><code>void a(int x) { std::cout &lt;&lt; x &lt;&lt; std::endl; }
  F(&amp;a, 7);
  </code></pre>
  
  <p>Giving error:
      invalid initialization of non-const reference of type ‘int&amp;’ from a temporary of type ‘int’  in passing argument 2 of ‘void F(void (*)(T), typename type_op::valid_ref_type) [with T = int]’</p>
  
  <p>How to get this trait to work?</p>