[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