0

How can I have a variant of different objects A, B, C where C has a reference to the variant?

class A {
   ...
};

class B {
   ...
};

class C {
   ...
   std::vector<PossibleValues> storage; // reference to variant
   ...
};

boost::variant<A, B, C> PossibleValues;
Tom
  • 1,235
  • 9
  • 22
  • 1
    Not possible, unless you use pointers. It's the same reason a class or structure can't contain its own type. – Some programmer dude Apr 20 '21 at 14:18
  • You can forward-declare each class that's `typedef`ed into the variant. Once the `typedef` is declared, define all the classes, then use the `typedef` to define instances of the variant. – Sam Varshavchik Apr 20 '21 at 14:19
  • @SamVarshavchik Finding it difficult to follow what you mean, could you provide a answer? – Tom Apr 20 '21 at 14:34
  • @Someprogrammerdude: `std::vector` "is" pointer like. `struct S { std::vector children; };` is possible. – Jarod42 Apr 20 '21 at 14:37
  • @Jarod42 Why did you delete your solution? I just tested it and it works. – Tom Apr 20 '21 at 14:57
  • `std::variant` cannot have incomplete type, (what my solution does, even if it compiles). It is ill-formed. – Jarod42 Apr 20 '21 at 15:02
  • In the answer referenced by @Jarod42, the conclusion looks wrong to me. The key quoted part is "... when instantiating a template component or evaluating a concept". A `typedef` declaration is not instantiating. A forward declaration, in this context, is 100% kosher. – Sam Varshavchik Apr 20 '21 at 15:30
  • @SamVarshavchik: According to [linked question](https://stackoverflow.com/questions/57226629/stdvariant-and-incomplete-type-how-does-it-work) `using V = std::variant` is ill formed. With boost, it might be fine though. and ignoring typedef, in `C`, we have `std::vector>` where `C` is still incomplete. – Jarod42 Apr 20 '21 at 15:39
  • Yes, according to the question it's ill-formed. However: I stated the reasoning why I believe the question is incorrect. `typedef` is not instantiation. – Sam Varshavchik Apr 20 '21 at 15:45

1 Answers1

1

With correct order, you might have:

class A {
   //...
};

class B {
   //...
};

class C;
using PossibleValues = std::variant<A, B, C>;

class C {
   //...
   std::vector<PossibleValues> storage; // reference to variant
   //...
};

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • It seems that `std::variant` can not have incomplete type, am I right? – Antoine Morrier Apr 20 '21 at 14:44
  • @AntoineMorrier: Indeed from [stdvariant-and-incomplete-type](https://stackoverflow.com/questions/57226629/stdvariant-and-incomplete-type-how-does-it-work). :-( – Jarod42 Apr 20 '21 at 14:50