C++ Logo

sg7

Advanced search

Re: [SG7] SG7 Digest, Vol 11, Issue 2

From: David Vandevoorde <daveed_at_[hidden]>
Date: Wed, 4 Nov 2020 12:47:04 -0500
> On Nov 4, 2020, at 11:27 AM, Andrew Sutton <asutton.list_at_[hidden]> wrote:
>
>> Even if you declare a forward class D the error still persists...
>>
>> struct A2 {
>> struct B {};
>> struct D;
>> consteval {
>> -> fragment struct {
>> B b = D(); //error
>> B getB() { return D(); } //error
>> };
>> }
>> struct D : B {};
>> };
>>
>>
>> Well, yeah. D hasn't been defined at the point it's used.
>
> Hmm, that’s an interesting case. One would expect that to work since doing the injection manually works:
>
> struct A2 {
> struct B {};
> struct D;
> B b = D(); // Okay.
> B getB() { return D(); } // Okay.
> struct D : B {};
> };
>
> The way implementations handle that is by saving the tokens of the “complete-context component" for replay later on. Presumably, the fragment handling implementation doesn’t do that, or it replays them before injection?
>
> The way our implementation works is that we do analysis of default inits, function bodies on the closing brace of the fragment. We don't consider the context to be the outermost class because it's a separate class (until it gets injected).

Right, I suspected so much. But it feels like quite the gotcha. OTOH, if we want to parse all fragment contents up front, I don’t know how to avoid it.

 Daveed


> Basically, it's more like this:
>
> struct A2 {
> struct B {};
> struct D;
> void f(decltype([](){ D(); });
> struct D : B {};
> };
>
> Just put the fragment in the lambda body.


Received on 2020-11-04 11:47:08