<html>
<head>
<base href="http://llvm.org/bugs/" />
</head>
<body><span class="vcard"><a class="email" href="mailto:richard-llvm@metafoo.co.uk" title="Richard Smith <richard-llvm@metafoo.co.uk>"> <span class="fn">Richard Smith</span></a>
</span> changed
<a class="bz_bug_link
bz_status_RESOLVED bz_closed"
title="RESOLVED INVALID - generic lambdas, decltype(auto), and rvalue references, oh my!"
href="http://llvm.org/bugs/show_bug.cgi?id=22426">bug 22426</a>
<br>
<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>What</th>
<th>Removed</th>
<th>Added</th>
</tr>
<tr>
<td style="text-align:right;">Status</td>
<td>NEW
</td>
<td>RESOLVED
</td>
</tr>
<tr>
<td style="text-align:right;">CC</td>
<td>
</td>
<td>richard-llvm@metafoo.co.uk
</td>
</tr>
<tr>
<td style="text-align:right;">Resolution</td>
<td>---
</td>
<td>INVALID
</td>
</tr></table>
<p>
<div>
<b><a class="bz_bug_link
bz_status_RESOLVED bz_closed"
title="RESOLVED INVALID - generic lambdas, decltype(auto), and rvalue references, oh my!"
href="http://llvm.org/bugs/show_bug.cgi?id=22426#c2">Comment # 2</a>
on <a class="bz_bug_link
bz_status_RESOLVED bz_closed"
title="RESOLVED INVALID - generic lambdas, decltype(auto), and rvalue references, oh my!"
href="http://llvm.org/bugs/show_bug.cgi?id=22426">bug 22426</a>
from <span class="vcard"><a class="email" href="mailto:richard-llvm@metafoo.co.uk" title="Richard Smith <richard-llvm@metafoo.co.uk>"> <span class="fn">Richard Smith</span></a>
</span></b>
<pre>(In reply to <a href="show_bug.cgi?id=22426#c0">comment #0</a>)
<span class="quote">> There should *never* be an error when using decltype(auto).</span >
That is true if the returned expression is a function call, but there are a few
cases where decltype(auto) returns can fail[1]. This is one of them.
decltype applied to the returned expression returns the declared type of the
member, due to a special case for class member access. In this case, the
declared type of the member is 'int &&', but the member access expression is an
int lvalue, so the reference binding fails.
You can get the result you expect here by a syntactic contortion: add another
pair of parens around your returned expression:
return (((decltype(p)&&)p).first);
This causes decltype to ignore that it's in the 'class member access
expression' special case. Note that this special case is in fact essential in
other uses of decltype(auto):
struct Q { int n; };
decltype(auto) f(Q q) { return q.n; }
Without the special case that is causing you problems here, the above function
would have return type 'int &' rather than 'int', which is obviously bad.
[1] This can happen in two ways:
1) the computed type is *not* the type of the expression plus & or && for
an lvalue or xvalue (this happens if we fall into [dcl.type.simple]/4.1)
2) the expression can't actually be used to initialize an object of its own
type
We're in case (1) here; for completeness, an example of case (2) would be:
struct X { int n : 1; };
decltype(auto) f(X x) { return (x.n); }
Here, decltype(auto) computes the type int&, which cannot bind to a bit-field.
Here's another:
unique_ptr<int> u;
decltype(auto) f() { return u; }</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>