title: How can I use decltype to get the type of a reference?
body: <p>I'm working on some code using decltype in CodeGear RAD Studio. I've tried the naive solution, which looks not unlike this:</p>
  
  <pre><code>int main(int, char**) {
      int i;
      int &amp;ir = i;
      decltype((ir)) ir_clone = ir;
  }
  </code></pre>
  
  <p>Of course, this fails to compile: Internal Compiler Error. I rather suspect that there is nothing particularly wrong with that code and there is a compiler bug regarding reference expressions. (Incidentally, g++ has no problem with the code and compiles it fine.) That doesn't help solve the problem, however, as the platform is non-negotiable.</p>
  
  <p>If, above, I had written</p>
  
  <pre><code>    decltype(ir) ir_clone = ir; /* No extra parens */
  </code></pre>
  
  <p>it compiles and works as expected. However, the problem doesn't end there, since that doesn't correctly compute constness from the environment. In particular:</p>
  
  <pre><code>struct S { int i; } s;
  const S* p = &amp;s;
  decltype(p-&gt;i)   i0 = s.i; /* i0 is an int */
  decltype((p-&gt;i)) i1 = s.i; /* i1 is a const int&amp; */
  </code></pre>
  
  <p>If I don't use the parens to make the argument an expression, I lose the constness of the argument, which I need.</p>
  
  <p>Another tool I can use is simple templates, like so:</p>
  
  <pre><code>template&lt;class T&gt; struct unref     { typedef T type; }
  template&lt;class T&gt; struct unref&lt;T&amp;&gt; { typedef T type; }
  </code></pre>
  
  <p>That lets me strip away the reference portion of a type, by using <code>unref&lt;int&amp;&gt;::type</code>.</p>
  
  <p>What I can't seem to figure out is how to put all these tools together to get a successful expression for the type I need. For one of things I need, I'm working on a generalized macro that does 'foreach'. (Yes, I know Boost does it better.) It needs to handle the following scenarios:</p>
  
  <pre><code>(vector&lt;int&gt;) vi          =&gt; vector&lt;int&gt;
  (vector&lt;int&gt;&amp;)vir         =&gt; vector&lt;int&gt;
  (const vector&lt;int&gt;) cvi   =&gt; const vector&lt;int&gt;
  (const vector&lt;int&gt;&amp;)cvir  =&gt; const vector&lt;int&gt;
  (const P*) cp-&gt;vi         =&gt; const vector&lt;int&gt;
  (P*) p-&gt;vi                =&gt; vector&lt;int&gt;
  </code></pre>
  
  <p>So far, my simple attempts fail:</p>
  
  <pre><code>unref&lt;decltype(cp-&gt;vi)&gt;   /* is vector&lt;int&gt;, not what I need. */
  unref&lt;decltype((cp-&gt;vi))&gt; /* is const vector&lt;int&gt;, which is right. */
  
  unref&lt;decltype(vir)&gt;      /* is vector&lt;int&gt;, which is right. */
  unref&lt;decltype((vir))&gt;    /* Internal Compiler Error, which is a headache. */
  </code></pre>
  
  <p>Any ideas to get me on the right track? Hopefully there's just something simple I'm missing. Maybe I'm attacking the problem from the wrong angle.</p>