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 {};



Em ter., 3 de nov. de 2020 às 15:40, Andrew Sutton via SG7 <sg7@lists.isocpp.org> escreveu:

This is a good point to consider on its own.  While I agree with the mental model that injection should result in "pasting" the contents into the enclosing context, given the different late-parsing behavior you describe, a user would get the following behavior, which probably won’t quite seem like pasting:

Code in question:

using namespace std::experimental;

struct A1 {
struct B {};
B b = D(); //works
B getB() { return D(); } //works
struct D : B {};

struct A2 {
struct B {};
consteval {
-> fragment struct {
B b = D(); //error
B getB() { return D(); } //error
struct D : B {};

Perhaps a better way to put it is that model is that an executing metaprogram is just like *parsing* the contained declarations into the enclosed context, after resolving any dependencies.  Parsing into a class does two things: 1. adds the essential content of the declarations immediately, and 2. defers parsing of the non-essentials until the closing brace of the outermost enclosing class.  Evaluation of a metaprogram should probably result in both distinct effects as well.

Circling back on this with fresh eyes... those errors are right. Injection *does* work that way. Things that would be deferred in a normal parse a deferred for injection also.

But these are errors because metaprograms are not parsed in the complete class context of A2 -- it's not deferred. Also, the class context of the fragment is different than that of A2/ It's more like a local class in an inline member function (at least I hope that's the right analogy).

SG7 mailing list