[PATCH] Local classes in templates (PR9685 fix)
Richard Smith
richard at metafoo.co.uk
Sun Aug 11 15:26:12 PDT 2013
On Sun, Aug 11, 2013 at 2:20 PM, Erik Olofsson <erik.olofsson at hansoft.se>wrote:
>
> How would DR1484 interact with function return type deduction. Would
> this still not require the patch?
>
This is a great question and example. We decided to keep DR1484 open so we
could consider the interaction with generic lambdas you point out below.
However, I think there's only one reasonable resolution.
Consider a generic lambda with a capture-default:
void g(int);
template<typename T> void g(const T&);
template<typename T> auto f() {
const T n = 0;
return [=] (auto x) { g(n); };
}
The behavior we want is that the lambda captures the same set of entities
it would have captured if we had manually substituted the template
parameter for its argument. So:
* f<float>'s returned lambda implicitly captures the local variable 'n'.
* f<int>'s returned lambda does not implicitly captures the local variable
'n', because 'g(n)' is a non-dependent expression that does not odr-use 'n'
(because 'n' is a constant expression to which an lvalue-to-rvalue
conversion is immediately applied).
In order to determine this, we *must* instantiate the lambda's body when
instantiating f<T>.
Another example that needs eager instantiation of generic lambda bodies:
template<typename T> void f() { [] () { T::error; }; } // f<int> is
ill-formed
template<typename T> void g() { [] (auto) { T::error; }; } // g<int> should
be ill-formed too
If we eagerly instantiate all generic lambdas, then we never need to refer
back into f<T>'s LocalInstantiationScope when instantiating the lambda's
call operator template, so this patch is not needed.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130811/f41c564b/attachment.html>
More information about the cfe-commits
mailing list