2

I want to create the following types

using Function = std::function<Variant(int)>;
using Variant = std::variant<int, bool, Function>;

In Variant I need to have Function as well, but Function should return a Variant (by value). However I cannot find the right syntax. I was trying to forward-declare Function, but I'm not sure how to do this.

As far as I know, I should be able to write such a thing, because forward-declaration is usually enough regarding the return type of a function.

Gábor
  • 71
  • 2
  • 4
    Does this answer your question? [Type aliasing and self-referencing](https://stackoverflow.com/questions/43689253/type-aliasing-and-self-referencing) – Vuwox Apr 20 '21 at 12:49

1 Answers1

6

You can scaffold it, sure. You just cannot have both identifiers be aliases. An alias cannot be forward declared.

Something like this:

struct Variant;
using Function = std::function<Variant(int)>;
struct Variant : std::variant<int, bool, Function> {
    using variant::variant;
};

Should work mostly as intended. The return type is incomplete initially (which should be okay so long as no operation is performed that requires it be complete). And then it's completed, by using the alias for Function.

The caveat is that Variant is now its own independent type. So some aspects of template argument deduction may work differently. But I doubt it's likely to rise up and bother you.

You also have the option of flipping the roles if needed. Be warned that the standard library may not be specified to behave reliably for types inheriting from its components. So some casting to a base class reference may be in order. Lay it out in the way that best works for you.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 1
    Until C++23 this `Variant` won't play nice with [`std::visit`](https://en.cppreference.com/w/cpp/utility/variant/visit). Maybe inheriting from the `std::function` would work better. – Quentin Apr 20 '21 at 12:52
  • @Quentin - I mean, yeah... but I believe this change is simply ratifying something that was commonly supported. – StoryTeller - Unslander Monica Apr 20 '21 at 12:58